<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Thank you, Peter! I'll take a look.<br>
      Unfortunately, there were no any buildbot e-mail complains about
      it so I didn't even notice the issue.<br>
      <br>
      20.12.2017 04:48, Peter Collingbourne пишет:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAPQLkRhHRz1x935-xfq0PxGFF5+7r8LpjmUxLNMa3KVf45Zexg@mail.gmail.com">
      <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"
            moz-do-not-send="true">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"
              moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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" moz-do-not-send="true">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"
              moz-do-not-send="true">cfe-commits@lists.llvm.org</a><br>
            <a
              href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits"
              rel="noreferrer" target="_blank" moz-do-not-send="true">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>
    </blockquote>
    <p><br>
    </p>
    <pre class="moz-signature" cols="72">-- 
Best regards,
Aleksei Sidorin,
SRR, Samsung Electronics
</pre>
  </body>
</html>