-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[ExtractAPI] Format typedef params correctly #171516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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
|
@llvm/pr-subscribers-clang Author: Prajwal Nadig (snprajwal) ChangesTypically, pointer types are formatted in a way where the identifier comes right after the type definition without a space separating them, e.g. This patch checks if pointer types are aliased, and inserts the space correctly if so. rdar://132022003 Full diff: https://github.com/llvm/llvm-project/pull/171516.diff 2 Files Affected:
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index e5eda46df8056..7f2778713eade 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -633,7 +633,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@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@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@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@bar"
+// BLOCKPTR-NEXT: },
+// BLOCKPTR: "kind": {
+// BLOCKPTR-NEXT: "displayName": "Function",
+// BLOCKPTR-NEXT: "identifier": "objective-c.func"
+// BLOCKPTR-NEXT: },
+
// expected-no-diagnostics
|
QuietMisdreavus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
|
/cherry-pick 794218b |
|
/pull-request #171522 |
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 794218b)
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 isint *and the identifier isfoo. 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:This patch checks if pointer types are aliased, and inserts the space correctly if so.
rdar://132022003