r236012 - Implemented ASTImporter support for Stmts and fixed

Sean Callanan scallanan at apple.com
Tue Apr 28 14:05:38 PDT 2015


Thanks.  I’ll see about adding the necessary support to ExprIterator.

Sean

> On Apr 28, 2015, at 1:57 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> 
> This change is failing for MSVC:
> 
> http://lab.llvm.org:8011/builders/lldb-x86-win7-msvc/builds/3432/steps/build/logs/stdio <http://lab.llvm.org:8011/builders/lldb-x86-win7-msvc/builds/3432/steps/build/logs/stdio>
> 
> Looks like the problem is that ExprIterator fails to satisfy the Iterator concept (it's missing iterator_category etc).
> 
> On Tue, Apr 28, 2015 at 11:41 AM, Sean Callanan <scallanan at apple.com <mailto:scallanan at apple.com>> wrote:
> Author: spyffe
> Date: Tue Apr 28 13:41:46 2015
> New Revision: 236012
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=236012&view=rev <http://llvm.org/viewvc/llvm-project?rev=236012&view=rev>
> Log:
> Implemented ASTImporter support for Stmts and fixed
> some bugs in the ASTImporter that this exposed:
> 
> - When importing functions, the body (if any) was
>   previously ignored.  This patch ensures that the
>   body is imported also.
> 
> - When a function-local Decl is imported, the first
>   thing the ASTImporter does is import its context
>   (via ImportDeclParts()).  This can trigger
>   importing the Decl again as part of the body of
>   the function (but only once, since the function's
>   Decl has been added to ImportedDecls).  This patch
>   fixes that problem by extending ImportDeclParts()
>   to return the imported Decl if it was imported as
>   part of importing its context, and the patch adds
>   ASTImporter::GetAlreadyImportedOrNull() to support
>   this query.  All callers of ImportDeclParts return
>   the imported version of the Decl if ImportDeclParts()
>   returns it.
> 
> - When creating functions, InnerLocStart of the source
>   function was re-used without importing.  This is a
>   straight up bug, and this patch makes ASTImporter
>   import the InnerLocStart and use the imported version.
> 
> - When importing FileIDs, the ASTImporter previously
>   always tried to re-load the file for the corresponding
>   CacheEntry from disk.  This doesn't work if the
>   CacheEntry corresponds to a named memory buffer.  This
>   patch changes the code so that if the UniqueID for the
>   cache entry is invalid (i.e., it is not a disk file)
>   the whole entry is treated as if it were invalid, which
>   forces an in-memory copy of the buffer.
> 
> Also added test cases, using the new support committed in
> 236011.
> 
> Added:
>     cfe/trunk/test/ASTMerge/Inputs/body1.c
>     cfe/trunk/test/ASTMerge/Inputs/body2.c
>     cfe/trunk/test/ASTMerge/codegen-body.c
>     cfe/trunk/test/ASTMerge/codegen-exprs.c
> Modified:
>     cfe/trunk/include/clang/AST/ASTImporter.h
>     cfe/trunk/lib/AST/ASTImporter.cpp
> 
> Modified: cfe/trunk/include/clang/AST/ASTImporter.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=236012&r1=236011&r2=236012&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=236012&r1=236011&r2=236012&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTImporter.h (original)
> +++ cfe/trunk/include/clang/AST/ASTImporter.h Tue Apr 28 13:41:46 2015
> @@ -121,6 +121,11 @@ namespace clang {
>      /// if an error occurred.
>      Decl *Import(Decl *FromD);
> 
> +    /// \brief Return the copy of the given declaration in the "to" context if
> +    /// it has already been imported from the "from" context.  Otherwise return
> +    /// NULL.
> +    Decl *GetAlreadyImportedOrNull(Decl *FromD);
> +
>      /// \brief Import the given declaration context from the "from"
>      /// AST context into the "to" AST context.
>      ///
> 
> Modified: cfe/trunk/lib/AST/ASTImporter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=236012&r1=236011&r2=236012&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=236012&r1=236011&r2=236012&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTImporter.cpp (original)
> +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Apr 28 13:41:46 2015
> @@ -81,7 +81,7 @@ namespace clang {
>      // Importing declarations
>      bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
>                           DeclContext *&LexicalDC, DeclarationName &Name,
> -                         SourceLocation &Loc);
> +                         NamedDecl *&ToD, SourceLocation &Loc);
>      void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
>      void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
>                                    DeclarationNameInfo& To);
> @@ -168,7 +168,44 @@ namespace clang {
>      Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
> 
>      // Importing statements
> +    DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
> +
>      Stmt *VisitStmt(Stmt *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);
> +    // FIXME: GCCAsmStmt
> +    // FIXME: MSAsmStmt
> +    // FIXME: SEHExceptStmt
> +    // FIXME: SEHFinallyStmt
> +    // FIXME: SEHTryStmt
> +    // FIXME: SEHLeaveStmt
> +    // FIXME: CapturedStmt
> +    Stmt *VisitCXXCatchStmt(CXXCatchStmt *S);
> +    Stmt *VisitCXXTryStmt(CXXTryStmt *S);
> +    Stmt *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);
> 
>      // Importing expressions
>      Expr *VisitExpr(Expr *E);
> @@ -182,6 +219,9 @@ namespace clang {
>      Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
>      Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
>      Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
> +    Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
> +    Expr *VisitMemberExpr(MemberExpr *E);
> +    Expr *VisitCallExpr(CallExpr *E);
>    };
>  }
>  using namespace clang;
> @@ -1830,6 +1870,7 @@ ASTNodeImporter::VisitObjCObjectPointerT
>  bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
>                                        DeclContext *&LexicalDC,
>                                        DeclarationName &Name,
> +                                      NamedDecl *&ToD,
>                                        SourceLocation &Loc) {
>    // Import the context of this declaration.
>    DC = Importer.ImportContext(D->getDeclContext());
> @@ -1850,6 +1891,7 @@ bool ASTNodeImporter::ImportDeclParts(Na
> 
>    // Import the location of this declaration.
>    Loc = Importer.Import(D->getLocation());
> +  ToD = cast_or_null<NamedDecl>(Importer.GetAlreadyImportedOrNull(D));
>    return false;
>  }
> 
> @@ -2031,7 +2073,7 @@ bool ASTNodeImporter::ImportDefinition(R
> 
>  bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
>                                         ImportDefinitionKind Kind) {
> -  if (To->getDefinition())
> +  if (To->getAnyInitializer())
>      return false;
> 
>    // FIXME: Can we really import any initializer? Alternatively, we could force
> @@ -2261,8 +2303,11 @@ Decl *ASTNodeImporter::VisitNamespaceDec
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    NamespaceDecl *MergeWithNamespace = nullptr;
>    if (!Name) {
> @@ -2329,8 +2374,11 @@ Decl *ASTNodeImporter::VisitTypedefNameD
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // If this typedef is not in block scope, determine whether we've
>    // seen a typedef with the same name (that we can merge with) or any
> @@ -2403,8 +2451,11 @@ Decl *ASTNodeImporter::VisitEnumDecl(Enu
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Figure out what enum name we're looking for.
>    unsigned IDNS = Decl::IDNS_Tag;
> @@ -2488,8 +2539,11 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Figure out what structure name we're looking for.
>    unsigned IDNS = Decl::IDNS_Tag;
> @@ -2614,8 +2668,11 @@ Decl *ASTNodeImporter::VisitEnumConstant
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    QualType T = Importer.Import(D->getType());
>    if (T.isNull())
> @@ -2670,8 +2727,11 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Try to find a function in our own ("to") context with the same name, same
>    // type, and in the same context as the function we're importing.
> @@ -2763,10 +2823,11 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    // Create the imported function.
>    TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
>    FunctionDecl *ToFunction = nullptr;
> +  SourceLocation InnerLocStart = Importer.Import(D->getInnerLocStart());
>    if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
>      ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
>                                              cast<CXXRecordDecl>(DC),
> -                                            D->getInnerLocStart(),
> +                                            InnerLocStart,
>                                              NameInfo, T, TInfo,
>                                              FromConstructor->isExplicit(),
>                                              D->isInlineSpecified(),
> @@ -2775,7 +2836,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    } else if (isa<CXXDestructorDecl>(D)) {
>      ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
>                                             cast<CXXRecordDecl>(DC),
> -                                           D->getInnerLocStart(),
> +                                           InnerLocStart,
>                                             NameInfo, T, TInfo,
>                                             D->isInlineSpecified(),
>                                             D->isImplicit());
> @@ -2783,7 +2844,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>                                             = dyn_cast<CXXConversionDecl>(D)) {
>      ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
>                                             cast<CXXRecordDecl>(DC),
> -                                           D->getInnerLocStart(),
> +                                           InnerLocStart,
>                                             NameInfo, T, TInfo,
>                                             D->isInlineSpecified(),
>                                             FromConversion->isExplicit(),
> @@ -2792,7 +2853,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>    } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
>      ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
>                                         cast<CXXRecordDecl>(DC),
> -                                       D->getInnerLocStart(),
> +                                       InnerLocStart,
>                                         NameInfo, T, TInfo,
>                                         Method->getStorageClass(),
>                                         Method->isInlineSpecified(),
> @@ -2800,7 +2861,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>                                         Importer.Import(D->getLocEnd()));
>    } else {
>      ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
> -                                      D->getInnerLocStart(),
> +                                      InnerLocStart,
>                                        NameInfo, T, TInfo, D->getStorageClass(),
>                                        D->isInlineSpecified(),
>                                        D->hasWrittenPrototype(),
> @@ -2831,6 +2892,13 @@ Decl *ASTNodeImporter::VisitFunctionDecl
>      ToFunction->setType(T);
>    }
> 
> +  // Import the body, if any.
> +  if (Stmt *FromBody = D->getBody()) {
> +    if (Stmt *ToBody = Importer.Import(FromBody)) {
> +      ToFunction->setBody(ToBody);
> +    }
> +  }
> +
>    // FIXME: Other bits to merge?
> 
>    // Add this function to the lexical context.
> @@ -2877,8 +2945,11 @@ Decl *ASTNodeImporter::VisitFieldDecl(Fi
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Determine whether we've already imported this field.
>    SmallVector<NamedDecl *, 2> FoundDecls;
> @@ -2933,8 +3004,11 @@ Decl *ASTNodeImporter::VisitIndirectFiel
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Determine whether we've already imported this field.
>    SmallVector<NamedDecl *, 2> FoundDecls;
> @@ -3000,8 +3074,11 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Determine whether we've already imported this ivar
>    SmallVector<NamedDecl *, 2> FoundDecls;
> @@ -3050,8 +3127,11 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Try to find a variable in our own ("to") context with the same name and
>    // in the same context as the variable we're importing.
> @@ -3159,6 +3239,10 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
>    Importer.Imported(D, ToVar);
>    LexicalDC->addDeclInternal(ToVar);
> 
> +  if (!D->isFileVarDecl() &&
> +      D->isUsed())
> +    ToVar->setIsUsed();
> +
>    // Merge the initializer.
>    if (ImportDefinition(D, ToVar))
>      return nullptr;
> @@ -3218,6 +3302,10 @@ Decl *ASTNodeImporter::VisitParmVarDecl(
>                                              T, TInfo, D->getStorageClass(),
>                                              /*FIXME: Default argument*/nullptr);
>    ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
> +
> +  if (D->isUsed())
> +    ToParm->setIsUsed();
> +
>    return Importer.Imported(D, ToParm);
>  }
> 
> @@ -3226,8 +3314,11 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    SmallVector<NamedDecl *, 2> FoundDecls;
>    DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
> @@ -3337,8 +3428,11 @@ Decl *ASTNodeImporter::VisitObjCCategory
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    ObjCInterfaceDecl *ToInterface
>      = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
> @@ -3461,8 +3555,11 @@ Decl *ASTNodeImporter::VisitObjCProtocol
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    ObjCProtocolDecl *MergeWithProtocol = nullptr;
>    SmallVector<NamedDecl *, 2> FoundDecls;
> @@ -3636,8 +3733,11 @@ Decl *ASTNodeImporter::VisitObjCInterfac
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Look for an existing interface with the same name.
>    ObjCInterfaceDecl *MergeWithIface = nullptr;
> @@ -3791,8 +3891,11 @@ Decl *ASTNodeImporter::VisitObjCProperty
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // Check whether we have already imported this property.
>    SmallVector<NamedDecl *, 2> FoundDecls;
> @@ -4022,8 +4125,11 @@ Decl *ASTNodeImporter::VisitClassTemplat
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // We may already have a template of the same name; try to find and match it.
>    if (!DC->isFunctionOrMethod()) {
> @@ -4210,8 +4316,11 @@ Decl *ASTNodeImporter::VisitVarTemplateD
>    DeclContext *DC, *LexicalDC;
>    DeclarationName Name;
>    SourceLocation Loc;
> -  if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
> +  NamedDecl *ToD;
> +  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
> +  if (ToD)
> +    return ToD;
> 
>    // We may already have a template of the same name; try to find and match it.
>    assert(!DC->isFunctionOrMethod() &&
> @@ -4393,10 +4502,457 @@ Decl *ASTNodeImporter::VisitVarTemplateS
>  // Import Statements
>  //----------------------------------------------------------------------------
> 
> -Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
> -  Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
> -    << S->getStmtClassName();
> -  return nullptr;
> +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) {
> +   Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
> +     << S->getStmtClassName();
> +   return nullptr;
> + }
> +
> +Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
> +  DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup());
> +  for (Decl *ToD : ToDG) {
> +    if (!ToD)
> +      return nullptr;
> +  }
> +  SourceLocation ToStartLoc = Importer.Import(S->getStartLoc());
> +  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());
> +}
> +
> +Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
> +  SmallVector<Stmt *, 4> ToStmts(S->size());
> +  auto &_Importer = this->Importer;
> +  std::transform(S->body_begin(), S->body_end(), ToStmts.begin(),
> +    [&_Importer](Stmt *CS) -> Stmt * {
> +      return _Importer.Import(CS);
> +    });
> +  for (Stmt *ToS : ToStmts) {
> +    if (!ToS)
> +      return nullptr;
> +  }
> +  SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
> +  SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
> +  return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
> +                                                    ToStmts,
> +                                                    ToLBraceLoc, ToRBraceLoc);
> +}
> +
> +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;
> +  SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc());
> +  SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc());
> +  SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
> +  return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS,
> +                                                ToCaseLoc, ToEllipsisLoc,
> +                                                ToColonLoc);
> +}
> +
> +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);
> +}
> +
> +Stmt *ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
> +  SourceLocation ToIdentLoc = Importer.Import(S->getIdentLoc());
> +  LabelDecl *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);
> +}
> +
> +Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
> +  SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc());
> +  ArrayRef<const Attr*> FromAttrs(S->getAttrs());
> +  SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
> +  ASTContext &_ToContext = Importer.getToContext();
> +  std::transform(FromAttrs.begin(), FromAttrs.end(), ToAttrs.begin(),
> +    [&_ToContext](const Attr *A) -> const Attr * {
> +      return A->clone(_ToContext);
> +    });
> +  for (const Attr *ToA : ToAttrs) {
> +    if (!ToA)
> +      return nullptr;
> +  }
> +  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
> +  if (!ToSubStmt && S->getSubStmt())
> +    return nullptr;
> +  return AttributedStmt::Create(Importer.getToContext(), ToAttrLoc,
> +                                ToAttrs, ToSubStmt);
> +}
> +
> +Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) {
> +  SourceLocation ToIfLoc = Importer.Import(S->getIfLoc());
> +  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, ToConditionVariable,
> +                                              ToCondition, ToThenStmt,
> +                                              ToElseLoc, ToElseStmt);
> +}
> +
> +Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *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;
> +  SwitchStmt *ToStmt = new (Importer.getToContext()) SwitchStmt(
> +                         Importer.getToContext(), ToConditionVariable,
> +                         ToCondition);
> +  Stmt *ToBody = Importer.Import(S->getBody());
> +  if (!ToBody && S->getBody())
> +    return nullptr;
> +  ToStmt->setBody(ToBody);
> +  ToStmt->setSwitchLoc(Importer.Import(S->getSwitchLoc()));
> +  // Now we have to re-chain the cases.
> +  SwitchCase *LastChainedSwitchCase = nullptr;
> +  for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr;
> +       SC = SC->getNextSwitchCase()) {
> +    SwitchCase *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC));
> +    if (!ToSC)
> +      return nullptr;
> +    if (LastChainedSwitchCase)
> +      LastChainedSwitchCase->setNextSwitchCase(ToSC);
> +    else
> +      ToStmt->setSwitchCaseList(ToSC);
> +    LastChainedSwitchCase = ToSC;
> +  }
> +  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);
> +}
> +
> +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);
> +}
> +
> +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);
> +}
> +
> +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);
> +}
> +
> +Stmt *ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
> +  SourceLocation ToContinueLoc = Importer.Import(S->getContinueLoc());
> +  return new (Importer.getToContext()) ContinueStmt(ToContinueLoc);
> +}
> +
> +Stmt *ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
> +  SourceLocation ToBreakLoc = Importer.Import(S->getBreakLoc());
> +  return new (Importer.getToContext()) BreakStmt(ToBreakLoc);
> +}
> +
> +Stmt *ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
> +  SourceLocation ToRetLoc = Importer.Import(S->getReturnLoc());
> +  Expr *ToRetExpr = Importer.Import(S->getRetValue());
> +  if (!ToRetExpr && S->getRetValue())
> +    return nullptr;
> +  VarDecl *NRVOCandidate = const_cast<VarDecl*>(S->getNRVOCandidate());
> +  VarDecl *ToNRVOCandidate = cast_or_null<VarDecl>(Importer.Import(NRVOCandidate));
> +  if (!ToNRVOCandidate && NRVOCandidate)
> +    return nullptr;
> +  return new (Importer.getToContext()) ReturnStmt(ToRetLoc, ToRetExpr,
> +                                                  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);
> +}
> +
> +Stmt *ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
> +  SourceLocation ToTryLoc = Importer.Import(S->getTryLoc());
> +  Stmt *ToTryBlock = Importer.Import(S->getTryBlock());
> +  if (!ToTryBlock && S->getTryBlock())
> +    return nullptr;
> +  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;
> +    else
> +      return nullptr;
> +  }
> +  return CXXTryStmt::Create(Importer.getToContext(), ToTryLoc, ToTryBlock,
> +                            ToHandlers);
> +}
> +
> +Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
> +  DeclStmt *ToRange =
> +    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt()));
> +  if (!ToRange && S->getRangeStmt())
> +    return nullptr;
> +  DeclStmt *ToBeginEnd =
> +    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginEndStmt()));
> +  if (!ToBeginEnd && S->getBeginEndStmt())
> +    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;
> +  DeclStmt *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 ToColonLoc = Importer.Import(S->getColonLoc());
> +  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
> +  return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBeginEnd,
> +                                                       ToCond, ToInc,
> +                                                       ToLoopVar, ToBody,
> +                                                       ToForLoc, ToColonLoc,
> +                                                       ToRParenLoc);
> +}
> +
> +Stmt *ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
> +  Stmt *ToElem = Importer.Import(S->getElement());
> +  if (!ToElem && S->getElement())
> +    return nullptr;
> +  Expr *ToCollect = Importer.Import(S->getCollection());
> +  if (!ToCollect && S->getCollection())
> +    return nullptr;
> +  Stmt *ToBody = Importer.Import(S->getBody());
> +  if (!ToBody && S->getBody())
> +    return nullptr;
> +  SourceLocation ToForLoc = Importer.Import(S->getForLoc());
> +  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
> +  return new (Importer.getToContext()) ObjCForCollectionStmt(ToElem,
> +                                                             ToCollect,
> +                                                             ToBody, ToForLoc,
> +                                                             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);
> +}
> +
> +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;
> +    else
> +      return nullptr;
> +  }
> +  Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyStmt());
> +  if (!ToAtFinallyStmt && S->getFinallyStmt())
> +    return nullptr;
> +  return ObjCAtTryStmt::Create(Importer.getToContext(),
> +                               ToAtTryLoc, ToAtTryStmt,
> +                               ToCatchStmts.begin(), ToCatchStmts.size(),
> +                               ToAtFinallyStmt);
> +}
> +
> +Stmt *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;
> +  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);
>  }
> 
>  //----------------------------------------------------------------------------
> @@ -4607,6 +5163,107 @@ Expr *ASTNodeImporter::VisitCStyleCastEx
>                                  Importer.Import(E->getRParenLoc()));
>  }
> 
> +Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
> +  QualType T = Importer.Import(E->getType());
> +  if (T.isNull())
> +    return nullptr;
> +
> +  CXXConstructorDecl *ToCCD =
> +    dyn_cast<CXXConstructorDecl>(Importer.Import(E->getConstructor()));
> +  if (!ToCCD && E->getConstructor())
> +    return nullptr;
> +
> +  size_t NumArgs = E->getNumArgs();
> +  SmallVector<Expr *, 1> ToArgs(NumArgs);
> +  ASTImporter &_Importer = Importer;
> +  std::transform(E->arg_begin(), E->arg_end(), ToArgs.begin(),
> +    [&_Importer](Expr *AE) -> Expr * {
> +      return _Importer.Import(AE);
> +    });
> +  for (Expr *ToA : ToArgs) {
> +    if (!ToA)
> +      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()));
> +}
> +
> +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;
> +
> +  ValueDecl *ToMember = dyn_cast<ValueDecl>(Importer.Import(E->getMemberDecl()));
> +  if (!ToMember && E->getMemberDecl())
> +    return nullptr;
> +
> +  DeclAccessPair ToFoundDecl = DeclAccessPair::make(
> +    dyn_cast<NamedDecl>(Importer.Import(E->getFoundDecl().getDecl())),
> +    E->getFoundDecl().getAccess());
> +
> +  DeclarationNameInfo ToMemberNameInfo(
> +    Importer.Import(E->getMemberNameInfo().getName()),
> +    Importer.Import(E->getMemberNameInfo().getLoc()));
> +
> +  if (E->hasExplicitTemplateArgs()) {
> +    return nullptr; // FIXME: handle template arguments
> +  }
> +
> +  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::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;
> +
> +  unsigned NumArgs = E->getNumArgs();
> +
> +  llvm::SmallVector<Expr *, 2> ToArgs(NumArgs);
> +
> +  for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) {
> +    Expr *FromArg = E->getArg(ai);
> +    Expr *ToArg = Importer.Import(FromArg);
> +    if (!ToArg)
> +      return nullptr;
> +    ToArgs[ai] = ToArg;
> +  }
> +
> +  Expr **ToArgs_Copied = new (Importer.getToContext())
> +    Expr*[NumArgs];
> +
> +  for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai)
> +    ToArgs_Copied[ai] = ToArgs[ai];
> +
> +  return new (Importer.getToContext())
> +    CallExpr(Importer.getToContext(), ToCallee,
> +             ArrayRef<Expr*>(ToArgs_Copied, NumArgs), T, E->getValueKind(),
> +             Importer.Import(E->getRParenLoc()));
> +}
> +
>  ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
>                           ASTContext &FromContext, FileManager &FromFileManager,
>                           bool MinimalImport)
> @@ -4658,6 +5315,17 @@ TypeSourceInfo *ASTImporter::Import(Type
>                          FromTSI->getTypeLoc().getLocStart());
>  }
> 
> +Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) {
> +  llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
> +  if (Pos != ImportedDecls.end()) {
> +    Decl *ToD = Pos->second;
> +    ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, ToD);
> +    return ToD;
> +  } else {
> +    return nullptr;
> +  }
> +}
> +
>  Decl *ASTImporter::Import(Decl *FromD) {
>    if (!FromD)
>      return nullptr;
> @@ -4949,8 +5617,9 @@ SourceLocation ASTImporter::Import(Sourc
>    FileID ToFileID = Import(Decomposed.first);
>    if (ToFileID.isInvalid())
>      return SourceLocation();
> -  return ToSM.getLocForStartOfFile(ToFileID)
> -             .getLocWithOffset(Decomposed.second);
> +  SourceLocation ret = ToSM.getLocForStartOfFile(ToFileID)
> +                           .getLocWithOffset(Decomposed.second);
> +  return ret;
>  }
> 
>  SourceRange ASTImporter::Import(SourceRange FromRange) {
> @@ -4974,7 +5643,8 @@ FileID ASTImporter::Import(FileID FromID
>    // Map the FileID for to the "to" source manager.
>    FileID ToID;
>    const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
> -  if (Cache->OrigEntry) {
> +  if (Cache->OrigEntry &&
> +      Cache->OrigEntry->getUniqueID() != llvm::sys::fs::UniqueID()) {
>      // FIXME: We probably want to use getVirtualFile(), so we don't hit the
>      // disk again
>      // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
> 
> Added: cfe/trunk/test/ASTMerge/Inputs/body1.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/body1.c?rev=236012&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/body1.c?rev=236012&view=auto>
> ==============================================================================
> --- cfe/trunk/test/ASTMerge/Inputs/body1.c (added)
> +++ cfe/trunk/test/ASTMerge/Inputs/body1.c Tue Apr 28 13:41:46 2015
> @@ -0,0 +1,6 @@
> +int f();
> +
> +int main()
> +{
> +  return f();
> +}
> 
> Added: cfe/trunk/test/ASTMerge/Inputs/body2.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/body2.c?rev=236012&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/body2.c?rev=236012&view=auto>
> ==============================================================================
> --- cfe/trunk/test/ASTMerge/Inputs/body2.c (added)
> +++ cfe/trunk/test/ASTMerge/Inputs/body2.c Tue Apr 28 13:41:46 2015
> @@ -0,0 +1,4 @@
> +__inline__ __attribute__ ((always_inline)) int f()
> +{
> +  return 2;
> +}
> 
> Added: cfe/trunk/test/ASTMerge/codegen-body.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/codegen-body.c?rev=236012&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/codegen-body.c?rev=236012&view=auto>
> ==============================================================================
> --- cfe/trunk/test/ASTMerge/codegen-body.c (added)
> +++ cfe/trunk/test/ASTMerge/codegen-body.c Tue Apr 28 13:41:46 2015
> @@ -0,0 +1,5 @@
> +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/body1.c
> +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/body2.c
> +// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s
> +// expected-no-diagnostics
> +
> 
> Added: cfe/trunk/test/ASTMerge/codegen-exprs.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/codegen-exprs.c?rev=236012&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/codegen-exprs.c?rev=236012&view=auto>
> ==============================================================================
> --- cfe/trunk/test/ASTMerge/codegen-exprs.c (added)
> +++ cfe/trunk/test/ASTMerge/codegen-exprs.c Tue Apr 28 13:41:46 2015
> @@ -0,0 +1,5 @@
> +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/exprs1.c
> +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/exprs2.c
> +// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
> +// expected-no-diagnostics
> +
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150428/5a78c93d/attachment.html>


More information about the cfe-commits mailing list