From 3d0a2d92576cd24a72774f4e39c0c6317e8e1686 Mon Sep 17 00:00:00 2001 From: Justin Buchanan Date: Thu, 12 Oct 2023 11:09:25 -0700 Subject: [PATCH] fix(cxx): use correct definition anchor spans for lambdas (#5890) --- kythe/cxx/indexer/cxx/IndexerASTHooks.cc | 17 ++++++++++++++--- kythe/cxx/indexer/cxx/testdata/BUILD | 1 + kythe/cxx/indexer/cxx/testdata/basic/lambda.cc | 16 +++++++++++++--- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/kythe/cxx/indexer/cxx/IndexerASTHooks.cc b/kythe/cxx/indexer/cxx/IndexerASTHooks.cc index 7859cd8b88..d1b4ff5634 100644 --- a/kythe/cxx/indexer/cxx/IndexerASTHooks.cc +++ b/kythe/cxx/indexer/cxx/IndexerASTHooks.cc @@ -3469,10 +3469,21 @@ bool IndexerASTVisitor::VisitFunctionDecl(clang::FunctionDecl* Decl) { if (IsFunctionDefinition && !Decl->isImplicit() && Decl->getBody() != nullptr) { + // For lambdas, Decl does not contain the correct SourceRange directly. + // Instead, we look at the "synthesized" lambda class and use it's beginning + // location as the start of the source range. + clang::SourceRange Range = Decl->getSourceRange(); + if (clang::CXXMethodDecl* MethodDecl = + llvm::dyn_cast(Decl)) { + const clang::CXXRecordDecl* Parent = MethodDecl->getParent(); + if (Parent->isLambda()) { + Range.setBegin(Parent->getSourceRange().getBegin()); + } + } + SourceRange DefinitionRange = NormalizeRange( - {TemplateKeywordLoc.isValid() ? TemplateKeywordLoc - : Decl->getSourceRange().getBegin(), - Decl->getSourceRange().getEnd()}); + {TemplateKeywordLoc.isValid() ? TemplateKeywordLoc : Range.getBegin(), + Range.getEnd()}); auto DefinitionRangeInContext = RangeInCurrentContext(Decl->isImplicit(), DeclNode, DefinitionRange); MaybeRecordFullDefinitionRange(DefinitionRangeInContext, DeclNode, diff --git a/kythe/cxx/indexer/cxx/testdata/BUILD b/kythe/cxx/indexer/cxx/testdata/BUILD index 416e9e210d..bfd80aade6 100644 --- a/kythe/cxx/indexer/cxx/testdata/BUILD +++ b/kythe/cxx/indexer/cxx/testdata/BUILD @@ -962,6 +962,7 @@ cc_indexer_test( cc_indexer_test( name = "lambda_test", srcs = ["basic/lambda.cc"], + ignore_dups = True, tags = ["basic"], ) diff --git a/kythe/cxx/indexer/cxx/testdata/basic/lambda.cc b/kythe/cxx/indexer/cxx/testdata/basic/lambda.cc index 13b9874bcc..8b298417c8 100644 --- a/kythe/cxx/indexer/cxx/testdata/basic/lambda.cc +++ b/kythe/cxx/indexer/cxx/testdata/basic/lambda.cc @@ -1,4 +1,14 @@ -// TODO(justinbuchanan): fix indexer to include leading '[](' in lambda anchor -//- @") {}" defines Lambda -//- Lambda.node/kind function +//- @"[]() {}" defines LambdaFn +//- LambdaFn.node/kind function auto fn = []() {}; + +//- @"[]() -> int { return 0; }" defines LambdaFn2 +//- LambdaFn2.node/kind function +auto fn2 = []() -> int { return 0; }; + +void outer() { + int i = 0; + //- @"[&i]() {}" defines LambdaFn3 + //- LambdaFn3.node/kind function + auto fn3 = [&i]() {}; +}