https://github.com/MythreyaK updated https://github.com/llvm/llvm-project/pull/170642
>From 64e2e838413b55262ab5cb925b80c69968b3c844 Mon Sep 17 00:00:00 2001 From: Mythreya <[email protected]> Date: Wed, 3 Dec 2025 21:41:40 -0800 Subject: [PATCH 1/4] Enable designator hints test --- .../clangd/unittests/InlayHintTests.cpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index feb4404b3d2bf..204c022851017 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1147,20 +1147,6 @@ TEST(ParameterHints, CopyOrMoveConstructor) { )cpp"); } -TEST(ParameterHints, AggregateInit) { - // FIXME: This is not implemented yet, but it would be a natural - // extension to show member names as hints here. - assertParameterHints(R"cpp( - struct Point { - int x; - int y; - }; - void bar() { - Point p{41, 42}; - } - )cpp"); -} - TEST(ParameterHints, UserDefinedLiteral) { // Do not hint call to user-defined literal operator. assertParameterHints(R"cpp( @@ -1746,6 +1732,19 @@ TEST(TypeHints, SubstTemplateParameterAliases) { } TEST(DesignatorHints, Basic) { + assertDesignatorHints(R"cpp( + struct Point { + int x; + int y; + }; + void bar() { + Point p{$x[[41]], $y[[42]]}; + } + )cpp", + ExpectedHint{".x=", "x"}, ExpectedHint{".y=", "y"}); +} + +TEST(DesignatorHints, BasicArray) { assertDesignatorHints(R"cpp( struct S { int x, y, z; }; S s {$x[[1]], $y[[2+2]]}; >From 50042b1b71d30f5eb4fca21d87a0ae4164f5c90b Mon Sep 17 00:00:00 2001 From: Mythreya <[email protected]> Date: Wed, 3 Dec 2025 23:49:16 -0800 Subject: [PATCH 2/4] [clangd] Add designator hints for parenthesis aggregate initialization --- clang-tools-extra/clangd/InlayHints.cpp | 20 +++++++++++++++++++ .../clangd/unittests/InlayHintTests.cpp | 13 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index 23bd02304a4fd..edd7b2d38e90c 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -699,6 +699,26 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> { return InstantiatedFunction->getParamDecl(ParamIdx); } + bool VisitCXXParenListInitExpr(CXXParenListInitExpr *E) { + // TODO: Lang check needed? + if (!Cfg.InlayHints.Designators && + AST.getLangOpts().LangStd >= LangStandard::Kind::lang_cxx20) + return true; + + if (const auto *CXXRecord = E->getType()->getAsCXXRecordDecl()) { + const auto &InitExprs = E->getInitExprs(); + auto RecordFields = CXXRecord->fields().begin(); + + for (size_t I = 0; I < InitExprs.size(); + ++I, RecordFields = std::next(RecordFields)) { + // TODO: is prepending "." sufficient? + addDesignatorHint(InitExprs[I]->getSourceRange(), + "." + RecordFields->getName().str()); + } + } + return true; + } + bool VisitInitListExpr(InitListExpr *Syn) { // We receive the syntactic form here (shouldVisitImplicitCode() is false). // This is the one we will ultimately attach designators to. diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 204c022851017..72e7be2f3d943 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1821,6 +1821,19 @@ TEST(DesignatorHints, NoCrash) { ExpectedHint{".b=", "b"}); } +TEST(DesignatorHints, BasicParenInit) { + assertDesignatorHints(R"cpp( + struct S { + int x; + int y; + int z; + }; + S s ($x[[1]], $y[[2+2]], $z[[4]]); + )cpp", + ExpectedHint{".x=", "x"}, ExpectedHint{".y=", "y"}, + ExpectedHint{".z=", "z"}); +} + TEST(InlayHints, RestrictRange) { Annotations Code(R"cpp( auto a = false; >From 44c272043ae470cc4213e18e96e5c38ad31ffb5e Mon Sep 17 00:00:00 2001 From: Mythreya <[email protected]> Date: Fri, 5 Dec 2025 23:28:53 -0800 Subject: [PATCH 3/4] code-review --- clang-tools-extra/clangd/InlayHints.cpp | 24 +++++++++++++------ .../clangd/unittests/InlayHintTests.cpp | 18 ++++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index edd7b2d38e90c..9476fe9deea57 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -700,22 +700,32 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> { } bool VisitCXXParenListInitExpr(CXXParenListInitExpr *E) { - // TODO: Lang check needed? - if (!Cfg.InlayHints.Designators && - AST.getLangOpts().LangStd >= LangStandard::Kind::lang_cxx20) + if (!Cfg.InlayHints.Designators) return true; if (const auto *CXXRecord = E->getType()->getAsCXXRecordDecl()) { const auto &InitExprs = E->getInitExprs(); + size_t InitInx = 0; + + // Inherited members are first + for (const auto &Base : CXXRecord->bases()) { + std::ignore = Base; + // For a base record, just use its name + // Base of base requires its own initialization; ParenListInitExpr or + // InitListExpr will be invoked separately for them + InitInx++; + } + + // Then the members defined in this record auto RecordFields = CXXRecord->fields().begin(); - for (size_t I = 0; I < InitExprs.size(); - ++I, RecordFields = std::next(RecordFields)) { - // TODO: is prepending "." sufficient? - addDesignatorHint(InitExprs[I]->getSourceRange(), + for (; InitInx < InitExprs.size(); + ++InitInx, RecordFields = std::next(RecordFields)) { + addDesignatorHint(InitExprs[InitInx]->getSourceRange(), "." + RecordFields->getName().str()); } } + return true; } diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 72e7be2f3d943..afa67c336b867 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1834,6 +1834,24 @@ TEST(DesignatorHints, BasicParenInit) { ExpectedHint{".z=", "z"}); } +TEST(DesignatorHints, BasicParenInitDerived) { + assertDesignatorHints(R"cpp( + struct S1 { + int a; + int b; + }; + + struct S2 : S1 { + int c; + int d; + }; + S2 s2 ({$a[[0]], $b[[0]]}, $c[[0]], $d[[0]]); + )cpp", + // ExpectedHint{"S1:", "S1"}, + ExpectedHint{".a=", "a"}, ExpectedHint{".b=", "b"}, + ExpectedHint{".c=", "c"}, ExpectedHint{".d=", "d"}); +} + TEST(InlayHints, RestrictRange) { Annotations Code(R"cpp( auto a = false; >From f93644dde03d17d4a60de4d3c754699fa27f5fcd Mon Sep 17 00:00:00 2001 From: Mythreya <[email protected]> Date: Sun, 7 Dec 2025 00:10:00 -0800 Subject: [PATCH 4/4] code-review --- clang-tools-extra/clangd/InlayHints.cpp | 11 +++----- .../clangd/unittests/InlayHintTests.cpp | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index 9476fe9deea57..040015cfc2d13 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -704,15 +704,12 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> { return true; if (const auto *CXXRecord = E->getType()->getAsCXXRecordDecl()) { - const auto &InitExprs = E->getInitExprs(); + const auto &InitExprs = E->getUserSpecifiedInitExprs(); size_t InitInx = 0; - // Inherited members are first - for (const auto &Base : CXXRecord->bases()) { - std::ignore = Base; - // For a base record, just use its name - // Base of base requires its own initialization; ParenListInitExpr or - // InitListExpr will be invoked separately for them + // Inherited members are first, skip them for now. + // FIXME: '.base=' or 'base:' hint? + for (const auto &_ : CXXRecord->bases()) { InitInx++; } diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index afa67c336b867..d54e36c2f8a3b 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1852,6 +1852,32 @@ TEST(DesignatorHints, BasicParenInitDerived) { ExpectedHint{".c=", "c"}, ExpectedHint{".d=", "d"}); } +TEST(DesignatorHints, BasicParenInitTemplate) { + assertDesignatorHints(R"cpp( + template <typename T> + struct S1 { + int a; + int b; + T* ptr; + }; + + struct S2 : S1<S2> { + int c; + int d; + S1<int> mem; + }; + + int main() { + S2 sa ({$a1[[0]], $b1[[0]]}, $c[[0]], $d[[0]], $mem[[S1<int>($a2[[1]], $b2[[2]], $ptr[[nullptr]])]]); + } + )cpp", + ExpectedHint{".a=", "a1"}, ExpectedHint{".b=", "b1"}, + ExpectedHint{".c=", "c"}, ExpectedHint{".d=", "d"}, + ExpectedHint{".mem=", "mem"}, ExpectedHint{".a=", "a2"}, + ExpectedHint{".b=", "b2"}, + ExpectedHint{".ptr=", "ptr"}); +} + TEST(InlayHints, RestrictRange) { Annotations Code(R"cpp( auto a = false; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
