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 <mailto: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
<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
<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
<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
<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 <mailto:cfe-commits@lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
<http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
--
--
Peter