diff --git a/clang/include/clang/Index/IndexingAction.h b/clang/include/clang/Index/IndexingAction.h index 36b3c75a65ff2..8b3d5415c063e 100644 --- a/clang/include/clang/Index/IndexingAction.h +++ b/clang/include/clang/Index/IndexingAction.h @@ -44,6 +44,8 @@ struct IndexingOptions { // callback is not available (e.g. after parsing has finished). Note that // macro references are not available in Proprocessor. bool IndexMacrosInPreprocessor = false; + // Has no effect if IndexFunctionLocals are false. + bool IndexParametersInDeclarations = false; }; /// Creates a frontend action that indexes all symbols (macros and AST decls). diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index aa73d937df315..eb0b3d4a70e35 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -88,12 +88,11 @@ class IndexingDeclVisitor : public ConstDeclVisitor { /*isBase=*/false, isIBType); IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent); if (IndexCtx.shouldIndexFunctionLocalSymbols()) { - // Only index parameters in definitions, parameters in declarations are - // not useful. if (const ParmVarDecl *Parm = dyn_cast(D)) { auto *DC = Parm->getDeclContext(); if (auto *FD = dyn_cast(DC)) { - if (FD->isThisDeclarationADefinition()) + if (IndexCtx.shouldIndexParametersInDeclarations() || + FD->isThisDeclarationADefinition()) IndexCtx.handleDecl(Parm); } else if (auto *MD = dyn_cast(DC)) { if (MD->isThisDeclarationADefinition()) @@ -102,7 +101,8 @@ class IndexingDeclVisitor : public ConstDeclVisitor { IndexCtx.handleDecl(Parm); } } else if (const FunctionDecl *FD = dyn_cast(D)) { - if (FD->isThisDeclarationADefinition()) { + if (IndexCtx.shouldIndexParametersInDeclarations() || + FD->isThisDeclarationADefinition()) { for (auto PI : FD->parameters()) { IndexCtx.handleDecl(PI); } diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp index 0bbd739d741c7..3d2d7d4ff02ae 100644 --- a/clang/lib/Index/IndexingContext.cpp +++ b/clang/lib/Index/IndexingContext.cpp @@ -40,6 +40,10 @@ bool IndexingContext::shouldIndexImplicitInstantiation() const { return IndexOpts.IndexImplicitInstantiation; } +bool IndexingContext::shouldIndexParametersInDeclarations() const { + return IndexOpts.IndexParametersInDeclarations; +} + bool IndexingContext::handleDecl(const Decl *D, SymbolRoleSet Roles, ArrayRef Relations) { diff --git a/clang/lib/Index/IndexingContext.h b/clang/lib/Index/IndexingContext.h index 1de38513c61ab..7765fa73f82c8 100644 --- a/clang/lib/Index/IndexingContext.h +++ b/clang/lib/Index/IndexingContext.h @@ -61,6 +61,8 @@ class IndexingContext { bool shouldIndexImplicitInstantiation() const; + bool shouldIndexParametersInDeclarations() const; + static bool isTemplateImplicitInstantiation(const Decl *D); bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(), diff --git a/clang/unittests/Index/IndexTests.cpp b/clang/unittests/Index/IndexTests.cpp index 147f7a714ad24..2b574a53fc323 100644 --- a/clang/unittests/Index/IndexTests.cpp +++ b/clang/unittests/Index/IndexTests.cpp @@ -119,6 +119,21 @@ TEST(IndexTest, IndexPreprocessorMacros) { EXPECT_THAT(Index->Symbols, UnorderedElementsAre()); } +TEST(IndexTest, IndexParametersInDecls) { + std::string Code = "void foo(int bar);"; + auto Index = std::make_shared(); + IndexingOptions Opts; + Opts.IndexFunctionLocals = true; + Opts.IndexParametersInDeclarations = true; + tooling::runToolOnCode(new IndexAction(Index, Opts), Code); + EXPECT_THAT(Index->Symbols, Contains(QName("bar"))); + + Opts.IndexParametersInDeclarations = false; + Index->Symbols.clear(); + tooling::runToolOnCode(new IndexAction(Index, Opts), Code); + EXPECT_THAT(Index->Symbols, Not(Contains(QName("bar")))); +} + } // namespace } // namespace index } // namespace clang