Skip to content

Commit d9cb76b

Browse files
[clang] Support function pointer types with attributes when extracting parameter names for signature help
Fixes clangd/clangd#1729 Differential Revision: https://reviews.llvm.org/D157952
1 parent 29f11e4 commit d9cb76b

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,20 +1397,37 @@ TEST(SignatureHelpTest, Overloads) {
13971397
}
13981398

13991399
TEST(SignatureHelpTest, FunctionPointers) {
1400-
auto FunctionPointerResults = signatures(R"cpp(
1400+
llvm::StringLiteral Tests[] = {
1401+
// Variable of function pointer type
1402+
R"cpp(
14011403
void (*foo)(int x, int y);
14021404
int main() { foo(^); }
1403-
)cpp");
1404-
EXPECT_THAT(FunctionPointerResults.signatures,
1405-
UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1406-
1407-
auto FunctionPointerTypedefResults = signatures(R"cpp(
1405+
)cpp",
1406+
// Wrapped in an AttributedType
1407+
R"cpp(
1408+
void (__stdcall *foo)(int x, int y);
1409+
int main() { foo(^); }
1410+
)cpp",
1411+
// Another syntax for an AttributedType
1412+
R"cpp(
1413+
void (__attribute__(stdcall) *foo)(int x, int y);
1414+
int main() { foo(^); },
1415+
)cpp",
1416+
// Wrapped in a typedef
1417+
R"cpp(
14081418
typedef void (*fn)(int x, int y);
14091419
fn foo;
14101420
int main() { foo(^); }
1411-
)cpp");
1412-
EXPECT_THAT(FunctionPointerTypedefResults.signatures,
1413-
UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1421+
)cpp",
1422+
// Wrapped in both a typedef and an AttributedTyped
1423+
R"cpp(
1424+
typedef void (__stdcall *fn)(int x, int y);
1425+
fn foo;
1426+
int main() { foo(^); }
1427+
)cpp"};
1428+
for (auto Test : Tests)
1429+
EXPECT_THAT(signatures(Test).signatures,
1430+
UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
14141431
}
14151432

14161433
TEST(SignatureHelpTest, Constructors) {

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6066,12 +6066,21 @@ static FunctionProtoTypeLoc GetPrototypeLoc(Expr *Fn) {
60666066
if (!Target)
60676067
return {};
60686068

6069-
if (auto P = Target.getAs<PointerTypeLoc>()) {
6070-
Target = P.getPointeeLoc();
6071-
}
6072-
6073-
if (auto P = Target.getAs<ParenTypeLoc>()) {
6074-
Target = P.getInnerLoc();
6069+
// Unwrap types that may be wrapping the function type
6070+
while (true) {
6071+
if (auto P = Target.getAs<PointerTypeLoc>()) {
6072+
Target = P.getPointeeLoc();
6073+
continue;
6074+
}
6075+
if (auto A = Target.getAs<AttributedTypeLoc>()) {
6076+
Target = A.getModifiedLoc();
6077+
continue;
6078+
}
6079+
if (auto P = Target.getAs<ParenTypeLoc>()) {
6080+
Target = P.getInnerLoc();
6081+
continue;
6082+
}
6083+
break;
60756084
}
60766085

60776086
if (auto F = Target.getAs<FunctionProtoTypeLoc>()) {

0 commit comments

Comments
 (0)