Hi, I reverted this change in r321139 because it causes a test failure on Windows. e.g. https://logs.chromium.org/v/?s=chromium%2Fbb%2Ftryserver.chromium.win%2Fwin_upload_clang%2F277%2F%2B%2Frecipes%2Fsteps%2Fpackage_clang%2F0%2Fstdout Please let me know if you have trouble reproducing.
Thanks, Peter On Sun, Dec 17, 2017 at 6:16 AM, Aleksei Sidorin via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: a.sidorin > Date: Sun Dec 17 06:16:17 2017 > New Revision: 320942 > > URL: http://llvm.org/viewvc/llvm-project?rev=320942&view=rev > Log: > [ASTImporter] Support importing FunctionTemplateDecl and > CXXDependentScopeMemberExpr > > * Also introduces ImportTemplateArgumentListInfo facility (A. Sidorin) > > Patch by Peter Szecsi! > > Differential Revision: https://reviews.llvm.org/D38692 > > Modified: > cfe/trunk/lib/AST/ASTImporter.cpp > cfe/trunk/unittests/AST/ASTImporterTest.cpp > > Modified: cfe/trunk/lib/AST/ASTImporter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/AST/ASTImporter.cpp (original) > +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Dec 17 06:16:17 2017 > @@ -134,12 +134,17 @@ namespace clang { > bool ImportTemplateArguments(const TemplateArgument *FromArgs, > unsigned NumFromArgs, > SmallVectorImpl<TemplateArgument> > &ToArgs); > + template <typename InContainerTy> > + bool ImportTemplateArgumentListInfo(const InContainerTy &Container, > + TemplateArgumentListInfo > &ToTAInfo); > bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, > bool Complain = true); > bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, > bool Complain = true); > bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); > bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl > *ToEC); > + bool IsStructuralMatch(FunctionTemplateDecl *From, > + FunctionTemplateDecl *To); > bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl > *To); > bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); > Decl *VisitDecl(Decl *D); > @@ -195,6 +200,7 @@ namespace clang { > ClassTemplateSpecializationDecl > *D); > Decl *VisitVarTemplateDecl(VarTemplateDecl *D); > Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl > *D); > + Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); > > // Importing statements > DeclGroupRef ImportDeclGroup(DeclGroupRef DG); > @@ -280,6 +286,7 @@ namespace clang { > Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); > Expr *VisitCXXConstructExpr(CXXConstructExpr *E); > Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); > + Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr > *E); > Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); > Expr *VisitCXXThisExpr(CXXThisExpr *E); > Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); > @@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArgu > return false; > } > > +template <typename InContainerTy> > +bool ASTNodeImporter::ImportTemplateArgumentListInfo( > + const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { > + for (const auto &FromLoc : Container) { > + if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) > + ToTAInfo.addArgument(*ToLoc); > + else > + return true; > + } > + return false; > +} > + > bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, > RecordDecl *ToRecord, bool > Complain) { > // Eliminate a potential failure point where we attempt to re-import > @@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch( > return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); > } > > +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, > + FunctionTemplateDecl *To) { > + StructuralEquivalenceContext Ctx( > + Importer.getFromContext(), Importer.getToContext(), > + Importer.getNonEquivalentDecls(), false, false); > + return Ctx.IsStructurallyEquivalent(From, To); > +} > + > bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, > EnumConstantDecl *ToEC) > { > @@ -4197,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateS > return D2; > } > > +Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl > *D) { > + DeclContext *DC, *LexicalDC; > + DeclarationName Name; > + SourceLocation 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. > + if (!LexicalDC->isFunctionOrMethod()) { > + unsigned IDNS = Decl::IDNS_Ordinary; > + SmallVector<NamedDecl *, 2> FoundDecls; > + DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); > + for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { > + if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) > + continue; > + > + if (FunctionTemplateDecl *FoundFunction = > + dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) { > + if (FoundFunction->hasExternalFormalLinkage() && > + D->hasExternalFormalLinkage()) { > + if (IsStructuralMatch(D, FoundFunction)) { > + Importer.Imported(D, FoundFunction); > + // FIXME: Actually try to merge the body and other attributes. > + return FoundFunction; > + } > + } > + } > + } > + } > + > + TemplateParameterList *Params = > + ImportTemplateParameterList(D->getTemplateParameters()); > + if (!Params) > + return nullptr; > + > + FunctionDecl *TemplatedFD = > + cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl())); > + if (!TemplatedFD) > + return nullptr; > + > + FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create( > + Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD); > + > + TemplatedFD->setDescribedFunctionTemplate(ToFunc); > + ToFunc->setAccess(D->getAccess()); > + ToFunc->setLexicalDeclContext(LexicalDC); > + Importer.Imported(D, ToFunc); > + > + LexicalDC->addDeclInternal(ToFunc); > + return ToFunc; > +} > + > //---------------------------------------------------------- > ------------------ > // Import Statements > //---------------------------------------------------------- > ------------------ > @@ -5759,6 +5844,47 @@ Expr *ASTNodeImporter::VisitCXXPseudoDes > Importer.Import(E->getTildeLoc()), Storage); > } > > +Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr( > + CXXDependentScopeMemberExpr *E) { > + Expr *Base = nullptr; > + if (!E->isImplicitAccess()) { > + Base = Importer.Import(E->getBase()); > + if (!Base) > + return nullptr; > + } > + > + QualType BaseType = Importer.Import(E->getBaseType()); > + if (BaseType.isNull()) > + return nullptr; > + > + TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()), > + Importer.Import(E->getRAngleLoc())); > + TemplateArgumentListInfo *ResInfo = nullptr; > + if (E->hasExplicitTemplateArgs()) { > + if (ImportTemplateArgumentListInfo(E->template_arguments(), > ToTAInfo)) > + return nullptr; > + ResInfo = &ToTAInfo; > + } > + > + DeclarationName Name = Importer.Import(E->getMember()); > + if (!E->getMember().isEmpty() && Name.isEmpty()) > + return nullptr; > + > + DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E-> > getMemberLoc())); > + // Import additional name location/type info. > + ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo); > + auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope()); > + if (!ToFQ && E->getFirstQualifierFoundInScope()) > + return nullptr; > + > + return CXXDependentScopeMemberExpr::Create( > + Importer.getToContext(), Base, BaseType, E->isArrow(), > + Importer.Import(E->getOperatorLoc()), > + Importer.Import(E->getQualifierLoc()), > + Importer.Import(E->getTemplateKeywordLoc()), > + cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo); > +} > + > Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { > QualType T = Importer.Import(E->getType()); > if (T.isNull()) > > Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ > AST/ASTImporterTest.cpp?rev=320942&r1=320941&r2=320942&view=diff > ============================================================ > ================== > --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) > +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Sun Dec 17 06:16:17 2017 > @@ -504,6 +504,35 @@ TEST(ImportType, ImportTypeAliasTemplate > declRefExpr())))))))))); > } > > +TEST(ImportDecl, ImportFunctionTemplateDecl) { > + MatchVerifier<Decl> Verifier; > + EXPECT_TRUE(testImport("template <typename T> void declToImport() { > };", > + Lang_CXX, "", Lang_CXX, Verifier, > + functionTemplateDecl())); > +} > + > +const internal::VariadicDynCastAllOfMatcher<Expr, > CXXDependentScopeMemberExpr> > + cxxDependentScopeMemberExpr; > + > +TEST(ImportExpr, ImportCXXDependentScopeMemberExpr) { > + MatchVerifier<Decl> Verifier; > + EXPECT_TRUE(testImport("template <typename T> class C { T t; };" > + "template <typename T> void declToImport() {" > + " C<T> d;" > + " d.t;" > + "}", > + Lang_CXX, "", Lang_CXX, Verifier, > + functionTemplateDecl(has( > functionDecl(has(compoundStmt( > + has(cxxDependentScopeMemberExpr())))))))); > + EXPECT_TRUE(testImport("template <typename T> class C { T t; };" > + "template <typename T> void declToImport() {" > + " C<T> d;" > + " (&d)->t;" > + "}", > + Lang_CXX, "", Lang_CXX, Verifier, > + functionTemplateDecl(has( > functionDecl(has(compoundStmt( > + has(cxxDependentScopeMemberExpr())))))))); > +} > > TEST(ImportType, ImportPackExpansion) { > MatchVerifier<Decl> Verifier; > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -- -- Peter
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits