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