r236012 - Implemented ASTImporter support for Stmts and fixed
Richard Smith
richard at metafoo.co.uk
Tue Apr 28 13:57:28 PDT 2015
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 <scallanan at apple.com> wrote:
> Author: spyffe
> Date: Tue Apr 28 13:41:46 2015
> New Revision: 236012
>
> URL: http://llvm.org/viewvc/llvm-project?rev=236012&view=rev
> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150428/cf84b68e/attachment.html>
More information about the cfe-commits
mailing list