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