Yep, I agree. I tend to figure if I can get it done in ~1-2 hours, that I could just fix it. Note that this was 1:30 😊
From: Nico Weber <tha...@chromium.org> Sent: Wednesday, October 2, 2019 4:37 PM To: Keane, Erich <erich.ke...@intel.com> Cc: cfe-commits <cfe-commits@lists.llvm.org> Subject: Re: r373247 - Teach CallGraph to look into Generic Lambdas. 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.ke...@intel.com<mailto:erich.ke...@intel.com>> wrote: Should be fixe din r373259 From: Nico Weber <tha...@chromium.org<mailto:tha...@chromium.org>> Sent: Monday, September 30, 2019 12:50 PM To: Keane, Erich <erich.ke...@intel.com<mailto:erich.ke...@intel.com>> Cc: cfe-commits <cfe-commits@lists.llvm.org<mailto:cfe-commits@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@lists.llvm.org<mailto:cfe-commits@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@lists.llvm.org<mailto:cfe-commits@lists.llvm.org> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits