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