llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Maria Fernanda Guimarães (mafeguimaraes) <details> <summary>Changes</summary> This PR addresses the issue where code completion inside `[...]` in HLSL mixed statement and declaration attributes. Previously, `ParseMicrosoftAttributes` called `CodeCompleteAttribute(AS_Microsoft)` without threading the `IsStmt `context, causing statement attributes (like `[unroll]`) and declaration attributes (like `[numthreads]`) to appear together, alongside semantic annotations (like `SV_Target`). Fixes #<!-- -->214792 --- Full diff: https://github.com/llvm/llvm-project/pull/215353.diff 6 Files Affected: - (modified) clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp (+49) - (modified) clang/include/clang/Parse/Parser.h (+5-3) - (modified) clang/include/clang/Sema/SemaCodeCompletion.h (+5) - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+13-5) - (modified) clang/lib/Parse/ParseStmt.cpp (+1-1) - (modified) clang/lib/Sema/SemaCodeComplete.cpp (+35) ``````````diff diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 4c1cab7b11e60..dca5ab072f537 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -5163,6 +5163,55 @@ TEST(CompletionTest, FuzzyMatchMacro) { } } +static void configureHLSL(TestTU &TU, bool EnableMatrix = false) { + TU.Filename = "TestTU.hlsl"; + TU.ExtraArgs.push_back("-x"); + TU.ExtraArgs.push_back("hlsl"); + if (EnableMatrix) + TU.ExtraArgs.push_back("-fenable-matrix"); + TU.ExtraArgs.push_back("--target=dxil-pc-shadermodel6.3-library"); +} + +TEST(CompletionTest, HLSLBracketAttributes) { + Annotations DeclContext(R"hlsl( + [^] + void main() {} + )hlsl"); + + TestTU TUDecl = TestTU::withCode(DeclContext.code()); + configureHLSL(TUDecl); + auto ResultsDecl = completions(TUDecl, DeclContext.point()); + + EXPECT_THAT(ResultsDecl.Completions, + Contains(Field(&CodeCompletion::Name, "numthreads"))); + EXPECT_THAT(ResultsDecl.Completions, + Contains(Field(&CodeCompletion::Name, "WaveSize"))); + EXPECT_THAT(ResultsDecl.Completions, + Not(Contains(Field(&CodeCompletion::Name, "unroll")))); + EXPECT_THAT(ResultsDecl.Completions, + Not(Contains(Field(&CodeCompletion::Name, "SV_Target")))); + + Annotations StmtContext(R"hlsl( + void main() { + [^] + for (int i = 0; i < 4; i++) {} + } + )hlsl"); + + TestTU TUStmt = TestTU::withCode(StmtContext.code()); + configureHLSL(TUStmt); + auto ResultsStmt = completions(TUStmt, StmtContext.point()); + + EXPECT_THAT(ResultsStmt.Completions, + Contains(Field(&CodeCompletion::Name, "unroll"))); + EXPECT_THAT(ResultsStmt.Completions, + Contains(Field(&CodeCompletion::Name, "loop"))); + EXPECT_THAT(ResultsStmt.Completions, + Not(Contains(Field(&CodeCompletion::Name, "numthreads")))); + EXPECT_THAT(ResultsStmt.Completions, + Not(Contains(Field(&CodeCompletion::Name, "SV_Target")))); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 163aa483a84e3..b7a311fd9fc6f 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2337,12 +2337,13 @@ class Parser : public CodeCompletionHandler { return false; } - bool MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) { + bool MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs, + bool IsStmtContext = false) { bool AttrsParsed = false; if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) && Tok.is(tok::l_square)) { ParsedAttributes AttrsWithRange(AttrFactory); - ParseMicrosoftAttributes(AttrsWithRange); + ParseMicrosoftAttributes(AttrsWithRange, IsStmtContext); AttrsParsed = !AttrsWithRange.empty(); Attrs.takeAllAppendingFrom(AttrsWithRange); } @@ -3133,7 +3134,8 @@ class Parser : public CodeCompletionHandler { /// ms-attribute[opt] /// ms-attribute ms-attribute-seq /// \endverbatim - void ParseMicrosoftAttributes(ParsedAttributes &Attrs); + void ParseMicrosoftAttributes(ParsedAttributes &Attrs, + bool IsStmtContext = false); void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs); void ParseNullabilityClassAttributes(ParsedAttributes &attrs); diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h index 7203b19d58898..b9fe3634992c0 100644 --- a/clang/include/clang/Sema/SemaCodeCompletion.h +++ b/clang/include/clang/Sema/SemaCodeCompletion.h @@ -234,6 +234,11 @@ class SemaCodeCompletion : public SemaBase { void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled); void CodeCompleteNaturalLanguage(); void CodeCompleteAvailabilityPlatformName(); + void CodeCompleteHLSLAttributes( + llvm::ArrayRef<AttributeCommonInfo::Syntax> Syntaxes, + std::optional<ParsedAttr::Kind> RestrictToKind = std::nullopt, + bool RequireStmt = false, + std::optional<ParsedAttr::Kind> ExcludeKind = std::nullopt); void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index a3617c3db49c4..0f01b9aae31f6 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4921,7 +4921,8 @@ void Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) { ParsedAttr::Form::Microsoft()); } -void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { +void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs, + bool IsStmtContext) { assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list"); SourceLocation StartLoc = Tok.getLocation(); @@ -4937,10 +4938,17 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) { StopAtSemi | StopBeforeMatch | StopAtCodeCompletion); if (Tok.is(tok::code_completion)) { cutOffParsing(); - Actions.CodeCompletion().CodeCompleteAttribute( - AttributeCommonInfo::AS_Microsoft, - SemaCodeCompletion::AttributeCompletion::Attribute, - /*Scope=*/nullptr); + if (getLangOpts().HLSL) { + Actions.CodeCompletion().CodeCompleteHLSLAttributes( + {AttributeCommonInfo::AS_Microsoft}, /*Kind=*/std::nullopt, + /*RequireStmt=*/IsStmtContext, + /*ExcludeKind=*/ParsedAttr::AT_HLSLParsedSemantic); + } else { + Actions.CodeCompletion().CodeCompleteAttribute( + AttributeCommonInfo::AS_Microsoft, + SemaCodeCompletion::AttributeCompletion::Attribute, + /*Scope=*/nullptr); + } break; } if (Tok.isNot(tok::identifier)) // ']', but also eof diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 219bcd980e860..b6d587cf96856 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -73,7 +73,7 @@ StmtResult Parser::ParseStatementOrDeclaration(StmtVector &Stmts, MaybeParseGNUAttributes(GNUOrMSAttrs); if (getLangOpts().HLSL) - MaybeParseMicrosoftAttributes(GNUOrMSAttrs); + MaybeParseMicrosoftAttributes(GNUOrMSAttrs, /*IsStmtContext=*/true); StmtResult Res = ParseStatementOrDeclarationAfterAttributes( Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs, diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index bd239adb0f215..cfca5ca715033 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -10728,6 +10728,41 @@ void SemaCodeCompletion::GatherGlobalCodeCompletions( Builder.data() + Builder.size()); } +void SemaCodeCompletion::CodeCompleteHLSLAttributes( + llvm::ArrayRef<AttributeCommonInfo::Syntax> Syntaxes, + std::optional<ParsedAttr::Kind> RestrictToKind, bool RequireStmt, + std::optional<ParsedAttr::Kind> ExcludeKind) { + ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + CodeCompletionContext::CCC_Attribute); + + for (const auto *A : ParsedAttrInfo::getAllBuiltin()) { + if (!A->acceptsLangOpts(getLangOpts())) + continue; + if (RestrictToKind && A->AttrKind != *RestrictToKind) + continue; + if (ExcludeKind && A->AttrKind == *ExcludeKind) + continue; + if (A->IsStmt != RequireStmt) + continue; + + for (const auto &S : A->Spellings) { + if (!llvm::is_contained(Syntaxes, S.Syntax)) + continue; + + CodeCompletionBuilder CCB(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + CCB.AddTypedTextChunk( + Results.getAllocator().CopyString(S.NormalizedFullName)); + Results.AddResult(CodeCompletionResult(CCB.TakeString(), CCP_Keyword)); + } + } + + HandleCodeCompleteResults(&SemaRef, CodeCompleter, + Results.getCompletionContext(), Results.data(), + Results.size()); +} + SemaCodeCompletion::SemaCodeCompletion(Sema &S, CodeCompleteConsumer *CompletionConsumer) : SemaBase(S), CodeCompleter(CompletionConsumer), `````````` </details> https://github.com/llvm/llvm-project/pull/215353 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
