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