Author: Nathan Ridge Date: 2023-08-18T00:27:15-04:00 New Revision: d9cb76bc4d5e903fe045c58a42fc791d0c70172b
URL: https://github.com/llvm/llvm-project/commit/d9cb76bc4d5e903fe045c58a42fc791d0c70172b DIFF: https://github.com/llvm/llvm-project/commit/d9cb76bc4d5e903fe045c58a42fc791d0c70172b.diff LOG: [clang] Support function pointer types with attributes when extracting parameter names for signature help Fixes https://github.com/clangd/clangd/issues/1729 Differential Revision: https://reviews.llvm.org/D157952 Added: Modified: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang/lib/Sema/SemaCodeComplete.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index dd6ee442244716..671c0b7da97c6c 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1397,20 +1397,37 @@ TEST(SignatureHelpTest, Overloads) { } TEST(SignatureHelpTest, FunctionPointers) { - auto FunctionPointerResults = signatures(R"cpp( + llvm::StringLiteral Tests[] = { + // Variable of function pointer type + R"cpp( void (*foo)(int x, int y); int main() { foo(^); } - )cpp"); - EXPECT_THAT(FunctionPointerResults.signatures, - UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void"))); - - auto FunctionPointerTypedefResults = signatures(R"cpp( + )cpp", + // Wrapped in an AttributedType + R"cpp( + void (__stdcall *foo)(int x, int y); + int main() { foo(^); } + )cpp", + // Another syntax for an AttributedType + R"cpp( + void (__attribute__(stdcall) *foo)(int x, int y); + int main() { foo(^); }, + )cpp", + // Wrapped in a typedef + R"cpp( typedef void (*fn)(int x, int y); fn foo; int main() { foo(^); } - )cpp"); - EXPECT_THAT(FunctionPointerTypedefResults.signatures, - UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void"))); + )cpp", + // Wrapped in both a typedef and an AttributedTyped + R"cpp( + typedef void (__stdcall *fn)(int x, int y); + fn foo; + int main() { foo(^); } + )cpp"}; + for (auto Test : Tests) + EXPECT_THAT(signatures(Test).signatures, + UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void"))); } TEST(SignatureHelpTest, Constructors) { diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index b9760e8e74452d..e3a2a21386e72c 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -6066,12 +6066,21 @@ static FunctionProtoTypeLoc GetPrototypeLoc(Expr *Fn) { if (!Target) return {}; - if (auto P = Target.getAs<PointerTypeLoc>()) { - Target = P.getPointeeLoc(); - } - - if (auto P = Target.getAs<ParenTypeLoc>()) { - Target = P.getInnerLoc(); + // Unwrap types that may be wrapping the function type + while (true) { + if (auto P = Target.getAs<PointerTypeLoc>()) { + Target = P.getPointeeLoc(); + continue; + } + if (auto A = Target.getAs<AttributedTypeLoc>()) { + Target = A.getModifiedLoc(); + continue; + } + if (auto P = Target.getAs<ParenTypeLoc>()) { + Target = P.getInnerLoc(); + continue; + } + break; } if (auto F = Target.getAs<FunctionProtoTypeLoc>()) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits