r373247 - Teach CallGraph to look into Generic Lambdas.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 2 16:37:24 PDT 2019


Thanks!

If it takes a few hours to investigate, I think it's better to revert first
and then investigate while the tree is green.

On Mon, Sep 30, 2019 at 4:43 PM Keane, Erich <erich.keane at intel.com> wrote:

> Should be fixe din r373259
>
>
>
> *From:* Nico Weber <thakis at chromium.org>
> *Sent:* Monday, September 30, 2019 12:50 PM
> *To:* Keane, Erich <erich.keane at intel.com>
> *Cc:* cfe-commits <cfe-commits at lists.llvm.org>
> *Subject:* Re: r373247 - Teach CallGraph to look into Generic Lambdas.
>
>
>
> This broke a few clangd unit tests:
>
>
>
>
> http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/38857/steps/ninja%20check%201/logs/FAIL%3A%20Clangd%20Unit%20Tests%3A%3AHover.Structured
>
>
> http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/38857/steps/ninja%20check%201/logs/FAIL%3A%20Clangd%20Unit%20Tests%3A%3AHover.All
>
> http://45.33.8.238/linux/680/step_7.txt
>
>
>
> On Mon, Sep 30, 2019 at 3:10 PM Erich Keane via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
> Author: erichkeane
> Date: Mon Sep 30 12:12:29 2019
> New Revision: 373247
>
> URL: http://llvm.org/viewvc/llvm-project?rev=373247&view=rev
> Log:
> Teach CallGraph to look into Generic Lambdas.
>
> CallGraph visited LambdaExpr by getting the Call Operator from
> CXXRecordDecl (LambdaExpr::getCallOperator calls
> CXXRecordDecl::getLambdaCallOperator), which replaced generic lambda
> call operators with the non-instantiated FunctionDecl.  The result was
> that the CallGraph would only pick up non-dependent calls.
>
> This patch does a few things:
> 1- Extend CXXRecordDecl to have a getDependentLambdaCallOperator, which
> will get the FunctionTemplateDecl, rather than immediately getting the
> TemplateDecl.
> 2- Define getLambdaCallOperator and getDependentLambdaCallOperator in
> terms of a common function.
> 3- Extend LambdaExpr with a getDependentCallOperator, which just calls
> the above function.
> 4- Changes CallGraph to handle Generic LambdaExprs.
>
> Modified:
>     cfe/trunk/include/clang/AST/DeclCXX.h
>     cfe/trunk/include/clang/AST/ExprCXX.h
>     cfe/trunk/lib/AST/DeclCXX.cpp
>     cfe/trunk/lib/AST/ExprCXX.cpp
>     cfe/trunk/lib/Analysis/CallGraph.cpp
>     cfe/trunk/test/Analysis/debug-CallGraph.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Sep 30 12:12:29 2019
> @@ -1172,6 +1172,10 @@ public:
>    /// if this is a closure type.
>    CXXMethodDecl *getLambdaCallOperator() const;
>
> +  /// Retrieve the dependent lambda call operator of the closure type
> +  /// if this is a templated closure type.
> +  FunctionTemplateDecl *getDependentLambdaCallOperator() const;
> +
>    /// Retrieve the lambda static invoker, the address of which
>    /// is returned by the conversion operator, and the body of which
>    /// is forwarded to the lambda call operator.
>
> Modified: cfe/trunk/include/clang/AST/ExprCXX.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
> +++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Sep 30 12:12:29 2019
> @@ -1907,6 +1907,10 @@ public:
>    /// lambda expression.
>    CXXMethodDecl *getCallOperator() const;
>
> +  /// Retrieve the function template call operator associated with this
> +  /// lambda expression.
> +  FunctionTemplateDecl *getDependentCallOperator() const;
> +
>    /// If this is a generic lambda expression, retrieve the template
>    /// parameter list associated with it, or else return null.
>    TemplateParameterList *getTemplateParameterList() const;
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Sep 30 12:12:29 2019
> @@ -1399,17 +1399,25 @@ static bool allLookupResultsAreTheSame(c
>  }
>  #endif
>
> -CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
> -  if (!isLambda()) return nullptr;
> +NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) {
> +  if (!RD.isLambda()) return nullptr;
>    DeclarationName Name =
> -    getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
> -  DeclContext::lookup_result Calls = lookup(Name);
> +    RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
> +  DeclContext::lookup_result Calls = RD.lookup(Name);
>
>    assert(!Calls.empty() && "Missing lambda call operator!");
>    assert(allLookupResultsAreTheSame(Calls) &&
>           "More than one lambda call operator!");
> +  return Calls.front();
> +}
> +
> +FunctionTemplateDecl* CXXRecordDecl::getDependentLambdaCallOperator()
> const {
> +  NamedDecl *CallOp = getLambdaCallOperatorHelper(*this);
> +  return  dyn_cast<FunctionTemplateDecl>(CallOp);
> +}
>
> -  NamedDecl *CallOp = Calls.front();
> +CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator() const {
> +  NamedDecl *CallOp = getLambdaCallOperatorHelper(*this);
>    if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp))
>      return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());
>
>
> Modified: cfe/trunk/lib/AST/ExprCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprCXX.cpp (original)
> +++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Sep 30 12:12:29 2019
> @@ -1218,6 +1218,11 @@ CXXMethodDecl *LambdaExpr::getCallOperat
>    return Record->getLambdaCallOperator();
>  }
>
> +FunctionTemplateDecl *LambdaExpr::getDependentCallOperator() const {
> +  CXXRecordDecl *Record = getLambdaClass();
> +  return Record->getDependentLambdaCallOperator();
> +}
> +
>  TemplateParameterList *LambdaExpr::getTemplateParameterList() const {
>    CXXRecordDecl *Record = getLambdaClass();
>    return Record->getGenericLambdaTemplateParameterList();
>
> Modified: cfe/trunk/lib/Analysis/CallGraph.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CallGraph.cpp?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Analysis/CallGraph.cpp (original)
> +++ cfe/trunk/lib/Analysis/CallGraph.cpp Mon Sep 30 12:12:29 2019
> @@ -80,7 +80,10 @@ public:
>    }
>
>    void VisitLambdaExpr(LambdaExpr *LE) {
> -    if (CXXMethodDecl *MD = LE->getCallOperator())
> +    if (FunctionTemplateDecl *FTD = LE->getDependentCallOperator())
> +      for (FunctionDecl *FD : FTD->specializations())
> +        G->VisitFunctionDecl(FD);
> +    else if (CXXMethodDecl *MD = LE->getCallOperator())
>        G->VisitFunctionDecl(MD);
>    }
>
>
> Modified: cfe/trunk/test/Analysis/debug-CallGraph.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/debug-CallGraph.cpp?rev=373247&r1=373246&r2=373247&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Analysis/debug-CallGraph.cpp (original)
> +++ cfe/trunk/test/Analysis/debug-CallGraph.cpp Mon Sep 30 12:12:29 2019
> @@ -1,4 +1,4 @@
> -// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s
> -fblocks 2>&1 | FileCheck %s
> +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s
> -fblocks -std=c++14 2>&1 | FileCheck %s
>
>  int get5() {
>    return 5;
> @@ -68,8 +68,25 @@ void templUser() {
>  }
>  }
>
> +namespace Lambdas {
> +  void Callee(){}
> +
> +  void f1() {
> +    [](int i) {
> +      Callee();
> +    }(1);
> +    [](auto i) {
> +      Callee();
> +    }(1);
> +  }
> +}
> +
>  // CHECK:--- Call graph Dump ---
> -// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa
> < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ
> SomeNS::templ SomeNS::templUser $}}
> +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa
> < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ
> SomeNS::templ SomeNS::templUser Lambdas::Callee Lambdas::f1
> Lambdas::f1\(\)::\(anonymous class\)::operator\(\)
> Lambdas::f1\(\)::\(anonymous class\)::operator\(\) $}}
> +// CHECK-NEXT: {{Function: Lambdas::f1 calls:
> Lambdas::f1\(\)::\(anonymous class\)::operator\(\)
> Lambdas::f1\(\)::\(anonymous class\)::operator\(\) $}}
> +// CHECK-NEXT: {{Function: Lambdas::f1\(\)::\(anonymous
> class\)::operator\(\) calls: Lambdas::Callee $}}
> +// CHECK-NEXT: {{Function: Lambdas::f1\(\)::\(anonymous
> class\)::operator\(\) calls: Lambdas::Callee $}}
> +// CHECK-NEXT: {{Function: Lambdas::Callee calls: $}}
>  // CHECK-NEXT: {{Function: SomeNS::templUser calls: SomeNS::templ
> SomeNS::templ $}}
>  // CHECK-NEXT: {{Function: SomeNS::templ calls: eee $}}
>  // CHECK-NEXT: {{Function: SomeNS::templ calls: ccc $}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191002/8f5db931/attachment.html>


More information about the cfe-commits mailing list