[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-28 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg closed 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 approved this pull request.


https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 deleted 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 requested changes to this pull request.

LGTM except for while loop

https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits


@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc &Block,
+ clang::FunctionProtoTypeLoc &BlockProto) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;

evelez7 wrote:

Wouldn't this while just break on the first iteration?

https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-24 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Daniel Grumberg (daniel-grumberg)


Changes

Ensure that block types get represented correctly in declaration fragments, as 
block parameter names are important for documentation clients we need a 
separate system from getFragmentsForType in order to have access to full 
ParmVarDecls for the parameters.

rdar://118257401

---

Patch is 36.77 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/73369.diff


7 Files Affected:

- (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+6) 
- (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+148-28) 
- (added) clang/test/ExtractAPI/objc_block.m (+965) 
- (modified) clang/test/ExtractAPI/objc_category.m (+4) 
- (modified) clang/test/ExtractAPI/objc_id_protocol.m (+8) 
- (modified) clang/test/ExtractAPI/objc_interface.m (+4) 
- (modified) clang/test/ExtractAPI/objc_property.m (+24) 


``diff
diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 316d83df13e9359..d719196b9a43ecb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -24,6 +24,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/SmallVector.h"
@@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a parameter variable declaration
   /// ParmVarDecl.
   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
+
+  static DeclarationFragments
+  getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
+   FunctionProtoTypeLoc &BlockProto,
+   DeclarationFragments &After);
 };
 
 template 
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 02fa6cd6119ecac..eb6eea0aaf54655 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/QualTypeNames.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc &Block,
+ clang::FunctionProtoTypeLoc &BlockProto) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;
+  }
+}
+
+} // namespace
+
 DeclarationFragments &DeclarationFragments::appendSpace() {
   if (!Fragments.empty()) {
 Fragment &Last = Fragments.back();
@@ -218,7 +254,7 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   // Declaration fragments of a pointer type is the declaration fragments of
   // the pointee type followed by a `*`,
-  if (T->isPointerType())
+  if (T->isPointerType() && !T->isFunctionPointerType())
 return Fragments
 .append(getFragmentsForType(T->getPointeeType(), Context, After))
 .append(" *", DeclarationFragments::FragmentKind::Text);
@@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
 .append(VarDecl::getStorageClassSpecifierString(SC),
 DeclarationFragments::FragmentKind::Keyword)
 .appendSpace();
-  QualType T =
-  Var->getTypeSourceInfo()
-  ? Var->getTypeSourceInfo()->getType()
-  : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
 
   // Capture potential fragments that needs to be placed after the variable 
name
   // ```
@@ -460,8 +492,23 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
   // char (*ptr_to_array)[6];
   // ```
   DeclarationFragments After;
-  return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
-  .appendSpace()
+  FunctionTypeLoc BlockLoc;
+  FunctionProtoTypeLoc BlockProtoLoc;
+  findTypeLocForBlockDecl(Var->getTypeSourceInf

[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-24 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg created 
https://github.com/llvm/llvm-project/pull/73369

Ensure that block types get represented correctly in declaration fragments, as 
block parameter names are important for documentation clients we need a 
separate system from getFragmentsForType in order to have access to full 
ParmVarDecls for the parameters.

rdar://118257401

>From e0a9db8aa5e511e81836b5f8e59853c0b498cadf Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 24 Nov 2023 20:34:49 +
Subject: [PATCH] [clang][ExtractAPI] Add support for blocks in declaration
 fragments

Ensure that block types get represented correctly in declaration
fragments, as block parameter names are important for documentation
clients we need a separate system from getFragmentsForType in order to
have access to full ParmVarDecls for the parameters.

rdar://118257401
---
 .../clang/ExtractAPI/DeclarationFragments.h   |   6 +
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 176 +++-
 clang/test/ExtractAPI/objc_block.m| 965 ++
 clang/test/ExtractAPI/objc_category.m |   4 +
 clang/test/ExtractAPI/objc_id_protocol.m  |   8 +
 clang/test/ExtractAPI/objc_interface.m|   4 +
 clang/test/ExtractAPI/objc_property.m |  24 +
 7 files changed, 1159 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/ExtractAPI/objc_block.m

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 316d83df13e9359..d719196b9a43ecb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -24,6 +24,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/SmallVector.h"
@@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a parameter variable declaration
   /// ParmVarDecl.
   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
+
+  static DeclarationFragments
+  getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
+   FunctionProtoTypeLoc &BlockProto,
+   DeclarationFragments &After);
 };
 
 template 
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 02fa6cd6119ecac..eb6eea0aaf54655 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/QualTypeNames.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc &Block,
+ clang::FunctionProtoTypeLoc &BlockProto) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;
+  }
+}
+
+} // namespace
+
 DeclarationFragments &DeclarationFragments::appendSpace() {
   if (!Fragments.empty()) {
 Fragment &Last = Fragments.back();
@@ -218,7 +254,7 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   // Declaration fragments of a pointer type is the declaration fragments of
   // the pointee type followed by a `*`,
-  if (T->isPointerType())
+  if (T->isPointerType() && !T->isFunctionPointerType())
 return Fragments
 .append(getFragmentsForType(T->getPointeeType(), Context, After))
 .append(" *", DeclarationFragments::FragmentKind::Text);
@@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
 .append(VarDecl::getStorageClassSpecifierString(SC),
 DeclarationFragments::FragmentKind::Keyword)
 .appendSpace();
-  QualType T =
-  Var->getTypeSourceInfo()
-  ? Var->getTypeSourceInfo()->getType()
-  : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
 
   // Capture potential fragments that needs to be placed