[llvm-branch-commits] [clang] release/21.x: [ExtractAPI] Format typedef params correctly (#171516) (PR #171522)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Dec 12 02:10:01 PST 2025
https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/171522
>From 7eb4bfe053d6bd81f42b0bfdd18ffd18fc081bc0 Mon Sep 17 00:00:00 2001
From: Prajwal Nadig <pnadig at apple.com>
Date: Tue, 9 Dec 2025 23:41:46 +0100
Subject: [PATCH] [ExtractAPI] Format typedef params correctly (#171516)
Typically, pointer types are formatted in a way where the identifier
comes right after the type definition without a space separating them,
e.g. `int *foo`, where the type is `int *` and the identifier is `foo`.
However, if a type alias to a pointer type is used, the emitted
declaration fragments are incorrect due to the missing space between the
type and identifier, like in the below example:
```
typedef int *T;
// The declaration fragment contains `Tbar` instead of `T bar`
void foo(T bar);
```
This patch checks if pointer types are aliased, and inserts the space
correctly if so.
rdar://132022003
(cherry picked from commit 794218bc53a42bd87048317506e8794deb0dc8be)
---
clang/lib/ExtractAPI/DeclarationFragments.cpp | 5 +-
clang/test/ExtractAPI/typedef.c | 81 ++++++++++++++++++-
2 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 791afc1a97575..00138c14ddcc2 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -636,7 +636,10 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
DeclarationFragments::FragmentKind::InternalParam);
} else {
Fragments.append(std::move(TypeFragments));
- if (!T->isAnyPointerType() && !T->isBlockPointerType())
+ // If the type is a type alias, append the space
+ // even if the underlying type is a pointer type.
+ if (T->isTypedefNameType() ||
+ (!T->isAnyPointerType() && !T->isBlockPointerType()))
Fragments.appendSpace();
Fragments
.append(Param->getName(),
diff --git a/clang/test/ExtractAPI/typedef.c b/clang/test/ExtractAPI/typedef.c
index a4c3619bfd210..6099cd62f8776 100644
--- a/clang/test/ExtractAPI/typedef.c
+++ b/clang/test/ExtractAPI/typedef.c
@@ -1,5 +1,5 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing -fblocks \
// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o %t/output.symbols.json -verify
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix MYINT
@@ -90,4 +90,83 @@ void foo(BarPtr value);
void baz(BarPtr *value);
// CHECK-NOT: struct Bar *
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix BLOCKPTR
+typedef int (^CustomType)(const unsigned int *, unsigned long);
+void bar(CustomType block);
+
+// BLOCKPTR-LABEL: "!testLabel": "c:@F at bar",
+// BLOCKPTR: "declarationFragments": [
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "typeIdentifier",
+// BLOCKPTR-NEXT: "preciseIdentifier": "c:v",
+// BLOCKPTR-NEXT: "spelling": "void"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "text",
+// BLOCKPTR-NEXT: "spelling": " "
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "identifier",
+// BLOCKPTR-NEXT: "spelling": "bar"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "text",
+// BLOCKPTR-NEXT: "spelling": "("
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "typeIdentifier",
+// BLOCKPTR-NEXT: "preciseIdentifier": "c:typedef.c at T@CustomType",
+// BLOCKPTR-NEXT: "spelling": "CustomType"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "text",
+// BLOCKPTR-NEXT: "spelling": " "
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "internalParam",
+// BLOCKPTR-NEXT: "spelling": "block"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "text",
+// BLOCKPTR-NEXT: "spelling": ");"
+// BLOCKPTR-NEXT: }
+// BLOCKPTR-NEXT: ],
+// BLOCKPTR-NEXT: "functionSignature": {
+// BLOCKPTR-NEXT: "parameters": [
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "declarationFragments": [
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "typeIdentifier",
+// BLOCKPTR-NEXT: "preciseIdentifier": "c:typedef.c at T@CustomType",
+// BLOCKPTR-NEXT: "spelling": "CustomType"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "text",
+// BLOCKPTR-NEXT: "spelling": " "
+// BLOCKPTR-NEXT: },
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "internalParam",
+// BLOCKPTR-NEXT: "spelling": "block"
+// BLOCKPTR-NEXT: }
+// BLOCKPTR-NEXT: ],
+// BLOCKPTR-NEXT: "name": "block"
+// BLOCKPTR-NEXT: }
+// BLOCKPTR-NEXT: ],
+// BLOCKPTR-NEXT: "returns": [
+// BLOCKPTR-NEXT: {
+// BLOCKPTR-NEXT: "kind": "typeIdentifier",
+// BLOCKPTR-NEXT: "preciseIdentifier": "c:v",
+// BLOCKPTR-NEXT: "spelling": "void"
+// BLOCKPTR-NEXT: }
+// BLOCKPTR-NEXT: ]
+// BLOCKPTR-NEXT: },
+// BLOCKPTR: "identifier": {
+// BLOCKPTR-NEXT: "interfaceLanguage": "objective-c",
+// BLOCKPTR-NEXT: "precise": "c:@F at bar"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR: "kind": {
+// BLOCKPTR-NEXT: "displayName": "Function",
+// BLOCKPTR-NEXT: "identifier": "objective-c.func"
+// BLOCKPTR-NEXT: },
+
// expected-no-diagnostics
More information about the llvm-branch-commits
mailing list