[clang] [clang][ExtractAPI] Fix up casting from CXXClassRecord (PR #110983)

2024-10-03 Thread Daniel Grumberg via cfe-commits

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

`RecordRecord::classOfKind` and `TagRecord::classofKind` didn't correctly 
capture `RK_CXXClass` and derived variants, e.g. `RK_ClassTemplate`. This 
materialized by anonymous C++ tag types not being correctly detected when they 
need to be merged with another record.

>From 0d94b2e151a3d2abde1139841100aef2e141ff94 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 3 Oct 2024 11:52:34 +0100
Subject: [PATCH] [clang][ExtractAPI] Fix up casting from CXXClassRecord

`RecordRecord::classOfKind` and `TagRecord::classofKind` didn't
correctly capture `RK_CXXClass` and derived variants, e.g.
`RK_ClassTemplate`. This materialized by anonymous C++ tag types not
being correctly detected when they need to be merged with another
record.
---
 clang/include/clang/ExtractAPI/API.h  | 37 +++-
 .../ExtractAPI/anonymous_record_no_typedef.c  | 44 +--
 .../ExtractAPI/typedef_anonymous_record.c | 27 +++-
 3 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 4f34fcc575e807..c30e6fac66d6ba 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -26,6 +26,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -615,7 +616,24 @@ struct TagRecord : APIRecord, RecordContext {
 return classofKind(Record->getKind());
   }
   static bool classofKind(RecordKind K) {
-return K == RK_Struct || K == RK_Union || K == RK_Enum;
+switch (K) {
+case RK_Enum:
+  LLVM_FALLTHROUGH;
+case RK_Struct:
+  LLVM_FALLTHROUGH;
+case RK_Union:
+  LLVM_FALLTHROUGH;
+case RK_CXXClass:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplate:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplateSpecialization:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplatePartialSpecialization:
+  return true;
+default:
+  return false;
+}
   }
 
   bool IsEmbeddedInVarDeclarator;
@@ -684,7 +702,22 @@ struct RecordRecord : TagRecord {
 return classofKind(Record->getKind());
   }
   static bool classofKind(RecordKind K) {
-return K == RK_Struct || K == RK_Union;
+switch (K) {
+case RK_Struct:
+  LLVM_FALLTHROUGH;
+case RK_Union:
+  LLVM_FALLTHROUGH;
+case RK_CXXClass:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplate:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplateSpecialization:
+  LLVM_FALLTHROUGH;
+case RK_ClassTemplatePartialSpecialization:
+  return true;
+default:
+  return false;
+}
   }
 
   bool isAnonymousWithNoTypedef() { return Name.empty(); }
diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c 
b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
index 064c223ad56e73..c0c76ef1f06b57 100644
--- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c
+++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
@@ -1,11 +1,18 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing \
 // RUN:   -triple arm64-apple-macosx -isystem %S 
-fretain-comments-from-system-headers \
-// RUN:   -x c-header %s -o %t/output.symbols.json -verify
+// RUN:   -x c-header %s -o %t/output-c.symbols.json -verify
+//
+// RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing \
+// RUN:   -triple arm64-apple-macosx -isystem %S 
-fretain-comments-from-system-headers \
+// RUN:   -x c++-header %s -o %t/output-cxx.symbols.json -verify
 
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBAL
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix PREFIX
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix CONTENT
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix 
GLOBAL
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix 
PREFIX
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix 
CONTENT
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix 
GLOBAL
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix 
PREFIX
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix 
CONTENT
 /// A global variable with an anonymous struct type.
 struct { char *prefix; char *content; } global;
 // GLOBAL-LABEL: "!testLabel": "c:@global"
@@ -30,7 +37,7 @@ struct { char *prefix; char *content; } global;
 // GLOBAL: "text": "A global variable with an anonymous struct type."
 // GLOBAL: "kind": {
 // GLOBAL-NEXT:  "displayName": "Global Variable",
-// GLOBAL-NEXT:  "identifier": "c.var"
+// GLOBAL-NEXT:  "identifier": "c{{(\+\+)?}}.var"
 // GLOBAL:   "title": "global"
 // GLOBAL: 

[clang] [clang][ExtractAPI] Generate subheading for typedef'd anonymous types (PR #110689)

2024-10-02 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Generate subheading for typedef'd anonymous types (PR #110689)

2024-10-02 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/110689

>From 30e06bed5b8ba378b2b43f0706617f6978f4be6c Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 1 Oct 2024 16:29:30 +0100
Subject: [PATCH] [clang][ExtractAPI] Generate subheading for typedef'd
 anonymous types

When an anonymous type has a typedef we normally use the typedef's name
in places where we expect a named identifier in the symbol graph. This
extends this logic to apply to subheadings.

rdar://136690614
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  3 ++
 .../ExtractAPI/typedef_anonymous_record.c | 32 +--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 9cb45c8fbf9cbc..66c03863293c2f 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1621,6 +1621,9 @@ DeclarationFragmentsBuilder::getSubHeading(const 
NamedDecl *Decl) {
  cast(Decl)->isOverloadedOperator()) {
 Fragments.append(Decl->getNameAsString(),
  DeclarationFragments::FragmentKind::Identifier);
+  } else if (isa(Decl) &&
+ cast(Decl)->getTypedefNameForAnonDecl()) {
+return getSubHeading(cast(Decl)->getTypedefNameForAnonDecl());
   } else if (Decl->getIdentifier()) {
 Fragments.append(Decl->getName(),
  DeclarationFragments::FragmentKind::Identifier);
diff --git a/clang/test/ExtractAPI/typedef_anonymous_record.c 
b/clang/test/ExtractAPI/typedef_anonymous_record.c
index 9c03e9e190ed6b..8e298f8d9ce829 100644
--- a/clang/test/ExtractAPI/typedef_anonymous_record.c
+++ b/clang/test/ExtractAPI/typedef_anonymous_record.c
@@ -35,7 +35,21 @@ typedef struct { } MyStruct;
 // MYSTRUCT:  "kind": {
 // MYSTRUCT-NEXT:   "displayName": "Structure",
 // MYSTRUCT-NEXT:   "identifier": "c.struct"
-// MYSTRUCT: "title": "MyStruct"
+// MYSTRUCT:   "names": {
+// MYSTRUCT-NEXT:"navigator": [
+// MYSTRUCT-NEXT:  {
+// MYSTRUCT-NEXT:"kind": "identifier",
+// MYSTRUCT-NEXT:"spelling": "MyStruct"
+// MYSTRUCT-NEXT:  }
+// MYSTRUCT-NEXT:],
+// MYSTRUCT-NEXT:"subHeading": [
+// MYSTRUCT-NEXT:  {
+// MYSTRUCT-NEXT:"kind": "identifier",
+// MYSTRUCT-NEXT:"spelling": "MyStruct"
+// MYSTRUCT-NEXT:  }
+// MYSTRUCT-NEXT:],
+// MYSTRUCT-NEXT:"title": "MyStruct"
+// MYSTRUCT-NEXT:  },
 // MYSTRUCT:  "pathComponents": [
 // MYSTRUCT-NEXT:"MyStruct"
 // MYSTRUCT-NEXT:  ]
@@ -111,7 +125,21 @@ typedef enum { Case } MyEnum;
 // MYENUM: "kind": {
 // MYENUM-NEXT:  "displayName": "Enumeration",
 // MYENUM-NEXT:  "identifier": "c.enum"
-// MYENUM: "title": "MyEnum"
+// MYENUM:   "names": {
+// MYENUM-NEXT:"navigator": [
+// MYENUM-NEXT:  {
+// MYENUM-NEXT:"kind": "identifier",
+// MYENUM-NEXT:"spelling": "MyEnum"
+// MYENUM-NEXT:  }
+// MYENUM-NEXT:],
+// MYENUM-NEXT:"subHeading": [
+// MYENUM-NEXT:  {
+// MYENUM-NEXT:"kind": "identifier",
+// MYENUM-NEXT:"spelling": "MyEnum"
+// MYENUM-NEXT:  }
+// MYENUM-NEXT:],
+// MYENUM-NEXT:"title": "MyEnum"
+// MYENUM-NEXT:  },
 
 // CASE-LABEL: "!testLabel": "c:@EA@MyEnum@Case"
 // CASE:  "pathComponents": [

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Generate subheading for typedef'd anonymous types (PR #110689)

2024-10-02 Thread Daniel Grumberg via cfe-commits


@@ -1621,6 +1621,9 @@ DeclarationFragmentsBuilder::getSubHeading(const 
NamedDecl *Decl) {
  cast(Decl)->isOverloadedOperator()) {
 Fragments.append(Decl->getNameAsString(),
  DeclarationFragments::FragmentKind::Identifier);
+  } else if (dyn_cast(Decl) &&

daniel-grumberg wrote:

absolutely

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


[clang] [clang][ExtractAPI] Generate subheading for typedef'd anonymous types (PR #110689)

2024-10-01 Thread Daniel Grumberg via cfe-commits

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

When an anonymous type has a typedef we normally use the typedef's name in 
places where we expect a named identifier in the symbol graph. This extends 
this logic to apply to subheadings.

rdar://136690614

>From 03b790809bbf3d59d031ff99886ac015c7f0864f Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 1 Oct 2024 16:29:30 +0100
Subject: [PATCH] [clang][ExtractAPI] Generate subheading for typedef'd
 anonymous types

When an anonymous type has a typedef we normally use the typedef's name
in places where we expect a named identifier in the symbol graph. This
extends this logic to apply to subheadings.

rdar://136690614
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  3 ++
 .../ExtractAPI/typedef_anonymous_record.c | 32 +--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 9cb45c8fbf9cbc..f2d4c905664560 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1621,6 +1621,9 @@ DeclarationFragmentsBuilder::getSubHeading(const 
NamedDecl *Decl) {
  cast(Decl)->isOverloadedOperator()) {
 Fragments.append(Decl->getNameAsString(),
  DeclarationFragments::FragmentKind::Identifier);
+  } else if (dyn_cast(Decl) &&
+ cast(Decl)->getTypedefNameForAnonDecl()) {
+return getSubHeading(cast(Decl)->getTypedefNameForAnonDecl());
   } else if (Decl->getIdentifier()) {
 Fragments.append(Decl->getName(),
  DeclarationFragments::FragmentKind::Identifier);
diff --git a/clang/test/ExtractAPI/typedef_anonymous_record.c 
b/clang/test/ExtractAPI/typedef_anonymous_record.c
index 9c03e9e190ed6b..8e298f8d9ce829 100644
--- a/clang/test/ExtractAPI/typedef_anonymous_record.c
+++ b/clang/test/ExtractAPI/typedef_anonymous_record.c
@@ -35,7 +35,21 @@ typedef struct { } MyStruct;
 // MYSTRUCT:  "kind": {
 // MYSTRUCT-NEXT:   "displayName": "Structure",
 // MYSTRUCT-NEXT:   "identifier": "c.struct"
-// MYSTRUCT: "title": "MyStruct"
+// MYSTRUCT:   "names": {
+// MYSTRUCT-NEXT:"navigator": [
+// MYSTRUCT-NEXT:  {
+// MYSTRUCT-NEXT:"kind": "identifier",
+// MYSTRUCT-NEXT:"spelling": "MyStruct"
+// MYSTRUCT-NEXT:  }
+// MYSTRUCT-NEXT:],
+// MYSTRUCT-NEXT:"subHeading": [
+// MYSTRUCT-NEXT:  {
+// MYSTRUCT-NEXT:"kind": "identifier",
+// MYSTRUCT-NEXT:"spelling": "MyStruct"
+// MYSTRUCT-NEXT:  }
+// MYSTRUCT-NEXT:],
+// MYSTRUCT-NEXT:"title": "MyStruct"
+// MYSTRUCT-NEXT:  },
 // MYSTRUCT:  "pathComponents": [
 // MYSTRUCT-NEXT:"MyStruct"
 // MYSTRUCT-NEXT:  ]
@@ -111,7 +125,21 @@ typedef enum { Case } MyEnum;
 // MYENUM: "kind": {
 // MYENUM-NEXT:  "displayName": "Enumeration",
 // MYENUM-NEXT:  "identifier": "c.enum"
-// MYENUM: "title": "MyEnum"
+// MYENUM:   "names": {
+// MYENUM-NEXT:"navigator": [
+// MYENUM-NEXT:  {
+// MYENUM-NEXT:"kind": "identifier",
+// MYENUM-NEXT:"spelling": "MyEnum"
+// MYENUM-NEXT:  }
+// MYENUM-NEXT:],
+// MYENUM-NEXT:"subHeading": [
+// MYENUM-NEXT:  {
+// MYENUM-NEXT:"kind": "identifier",
+// MYENUM-NEXT:"spelling": "MyEnum"
+// MYENUM-NEXT:  }
+// MYENUM-NEXT:],
+// MYENUM-NEXT:"title": "MyEnum"
+// MYENUM-NEXT:  },
 
 // CASE-LABEL: "!testLabel": "c:@EA@MyEnum@Case"
 // CASE:  "pathComponents": [

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Handle AttributedType fragments transparently (PR #107262)

2024-09-05 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Handle AttributedType fragments transparently (PR #107262)

2024-09-04 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/107262

>From 17a956e118879df9ce1431c41f580108b92b6784 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 3 Sep 2024 16:27:36 +0100
Subject: [PATCH] [clang][ExtractAPI] Handle AttributedType fragments
 transparently

rdar://131958623
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 13 ++
 clang/test/ExtractAPI/attributed-typedef.m| 24 +++
 2 files changed, 37 insertions(+)
 create mode 100644 clang/test/ExtractAPI/attributed-typedef.m

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index d77bb1d424f7cf..06ce5ed6a64756 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -276,6 +276,19 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   DeclarationFragments Fragments;
 
+  if (const MacroQualifiedType *MQT = dyn_cast(T)) {
+Fragments.append(
+getFragmentsForType(MQT->getUnderlyingType(), Context, After));
+return Fragments;
+  }
+
+  if (const AttributedType *AT = dyn_cast(T)) {
+// FIXME: Serialize Attributes correctly
+Fragments.append(
+getFragmentsForType(AT->getModifiedType(), Context, After));
+return Fragments;
+  }
+
   // An ElaboratedType is a sugar for types that are referred to using an
   // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
   // qualified name, e.g., `N::M::type`, or both.
diff --git a/clang/test/ExtractAPI/attributed-typedef.m 
b/clang/test/ExtractAPI/attributed-typedef.m
new file mode 100644
index 00..c948c873ab759c
--- /dev/null
+++ b/clang/test/ExtractAPI/attributed-typedef.m
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing \
+// RUN:   -triple arm64-apple-macosx -x objective-c-header %s -o 
%t/output.symbols.json
+
+_Pragma("clang assume_nonnull begin")
+
+struct Foo { int a; };
+typedef struct Foo *Bar;
+// RUN: FileCheck %s -input-file %t/output.symbols.json --check-prefix FUNC
+void func(Bar b);
+// FUNC-LABEL: "!testLabel": "c:@F@func",
+// CHECK-NOT: Foo
+// CHECK: "pathComponents"
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix THING
+#define SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
+extern Bar const thing SWIFT_NAME(swiftThing);
+// THING-LABEL: "!testLabel": "c:@thing"
+// THING-NOT: Foo
+// THING: "pathComponents"
+
+_Pragma("clang assume_nonnull end")
+
+// expected-no-diagnostics

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Handle AttributedType fragments transparently (PR #107262)

2024-09-04 Thread Daniel Grumberg via cfe-commits

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

rdar://131958623

>From 71011c910b218c4817872dee91499e60bd771e07 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 3 Sep 2024 16:27:36 +0100
Subject: [PATCH] [clang][ExtractAPI] Handle AttributedType fragments
 transparently

rdar://131958623
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 11 +
 clang/test/ExtractAPI/attributed-typedef.m| 24 +++
 2 files changed, 35 insertions(+)
 create mode 100644 clang/test/ExtractAPI/attributed-typedef.m

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index d77bb1d424f7cf..a95ab06534b737 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -276,6 +276,17 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   DeclarationFragments Fragments;
 
+  if (const MacroQualifiedType *MQT = dyn_cast(T)) {
+Fragments.append(getFragmentsForType(MQT->getUnderlyingType(), Context, 
After));
+return Fragments;
+  }
+
+  if (const AttributedType *AT = dyn_cast(T)) {
+// FIXME: Serialize Attributes correctly
+Fragments.append(getFragmentsForType(AT->getModifiedType(), Context, 
After));
+return Fragments;
+  }
+
   // An ElaboratedType is a sugar for types that are referred to using an
   // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
   // qualified name, e.g., `N::M::type`, or both.
diff --git a/clang/test/ExtractAPI/attributed-typedef.m 
b/clang/test/ExtractAPI/attributed-typedef.m
new file mode 100644
index 00..c948c873ab759c
--- /dev/null
+++ b/clang/test/ExtractAPI/attributed-typedef.m
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing \
+// RUN:   -triple arm64-apple-macosx -x objective-c-header %s -o 
%t/output.symbols.json
+
+_Pragma("clang assume_nonnull begin")
+
+struct Foo { int a; };
+typedef struct Foo *Bar;
+// RUN: FileCheck %s -input-file %t/output.symbols.json --check-prefix FUNC
+void func(Bar b);
+// FUNC-LABEL: "!testLabel": "c:@F@func",
+// CHECK-NOT: Foo
+// CHECK: "pathComponents"
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix THING
+#define SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
+extern Bar const thing SWIFT_NAME(swiftThing);
+// THING-LABEL: "!testLabel": "c:@thing"
+// THING-NOT: Foo
+// THING: "pathComponents"
+
+_Pragma("clang assume_nonnull end")
+
+// expected-no-diagnostics

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove erroneous module name check in MacroCallbacks (PR #107059)

2024-09-03 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Remove erroneous module name check in MacroCallbacks (PR #107059)

2024-09-03 Thread Daniel Grumberg via cfe-commits

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

rdar://135044923

>From caf560529093f80b5b6e6220ec19e244f57779d3 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Mon, 2 Sep 2024 18:47:40 +0100
Subject: [PATCH] [clang][ExtractAPI] Remove erroneous module name check in
 MacroCallbacks

rdar://135044923
---
 clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp 
b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 0adc23280fd6c0..75c2dec22400b9 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -350,7 +350,7 @@ class APIMacroCallback : public MacroCallback {
   bool shouldMacroBeIncluded(const SourceLocation &MacroLoc,
  StringRef ModuleName) override {
 // Do not include macros from external files
-return LCF(MacroLoc) || API.ProductName == ModuleName;
+return LCF(MacroLoc);
   }
 
 private:

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Fix iteration order of TopLevelRecords (PR #106411)

2024-08-29 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Fix iteration order of TopLevelRecords (PR #106411)

2024-08-28 Thread Daniel Grumberg via cfe-commits

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

Fixes #106355

>From 5b47537dd49e79e102f7a809b434c18086274b4b Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 28 Aug 2024 17:03:22 +0100
Subject: [PATCH] [clang][ExtractAPI] Fix iteration order of TopLevelRecords

---
 clang/include/clang/ExtractAPI/API.h | 11 +--
 clang/lib/ExtractAPI/API.cpp |  6 --
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 188e35b72117b5..4f34fcc575e807 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -23,7 +23,7 @@
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/TargetParser/Triple.h"
@@ -1420,9 +1420,8 @@ class APISet {
   typename std::enable_if_t, RecordTy> *
   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
 
-  auto getTopLevelRecords() const {
-return llvm::iterator_range(
-TopLevelRecords);
+  ArrayRef getTopLevelRecords() const {
+return TopLevelRecords;
   }
 
   void removeRecord(StringRef USR);
@@ -1455,7 +1454,7 @@ class APISet {
   // lives in the BumpPtrAllocator.
   using APIRecordStoredPtr = std::unique_ptr;
   llvm::DenseMap USRBasedLookupTable;
-  llvm::SmallPtrSet TopLevelRecords;
+  llvm::SmallVector TopLevelRecords;
 
 public:
   const std::string ProductName;
@@ -1481,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
 dyn_cast_if_present(Record->Parent.Record))
   ParentContext->addToRecordChain(Record);
 else
-  TopLevelRecords.insert(Record);
+  TopLevelRecords.push_back(Record);
   } else {
 Record = dyn_cast(Result.first->second.get());
   }
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index 9dbc023885c37f..a6ca0ae8d0d51d 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -150,11 +150,13 @@ void APISet::removeRecord(StringRef USR) {
   if (auto *RecordAsCtx = llvm::dyn_cast(Record))
 ParentCtx->stealRecordChain(*RecordAsCtx);
 } else {
-  TopLevelRecords.erase(Record);
+  auto *It = llvm::find(TopLevelRecords, Record);
+  if (It != TopLevelRecords.end())
+TopLevelRecords.erase(It);
   if (auto *RecordAsCtx = llvm::dyn_cast(Record)) {
 for (const auto *Child = RecordAsCtx->First; Child != nullptr;
  Child = Child->getNextInContext())
-  TopLevelRecords.insert(Child);
+  TopLevelRecords.push_back(Child);
   }
 }
 USRBasedLookupTable.erase(Result);

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Fix quirks in interaction with submodules (PR #105868)

2024-08-27 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Fix quirks in interaction with submodules (PR #105868)

2024-08-23 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/105868

>From b687c9512b748ee593eedd5e06d04d2a40197ec3 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 23 Aug 2024 10:02:42 +0100
Subject: [PATCH 1/5] [clang][ExtractAPI] Use top level module name for
 tracking which module a symbol came from

rdar://123020565
---
 clang/include/clang/ExtractAPI/ExtractAPIVisitor.h   | 2 +-
 clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 67659f5a25037c..b09b8b44d9abaa 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -213,7 +213,7 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 
   StringRef getOwningModuleName(const Decl &D) {
 if (auto *OwningModule = D.getImportedOwningModule())
-  return OwningModule->Name;
+  return OwningModule->getTopLevelModule()->Name;
 
 return {};
   }
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 1bce9c59b19791..54124ddbb2f58a 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -928,8 +928,8 @@ bool SymbolGraphSerializer::traverseObjCCategoryRecord(
 return true;
 
   auto *CurrentModule = ModuleForCurrentSymbol;
-  if (Record->isExtendingExternalModule())
-ModuleForCurrentSymbol = &ExtendedModules[Record->Interface.Source];
+  if (auto ModuleExtendedByRecord= Record->getExtendedExternalModule())
+ModuleForCurrentSymbol = &ExtendedModules[*ModuleExtendedByRecord];
 
   if (!walkUpFromObjCCategoryRecord(Record))
 return false;

>From dc061de96ede86df0afdb01bde797c3965760ebb Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 23 Aug 2024 18:16:50 +0100
Subject: [PATCH 2/5] [clang][ExtractAPI] Fix macro detection code to work with
 modules enabled

Change macro detection from using `MacroDefined` callback to iterating
over all visible macros in `EndOfMainFile` callback. This way macros
that came from an ASTFile are taken into account.
---
 .../clang/ExtractAPI/DeclarationFragments.h   |   4 +-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |   4 +-
 clang/lib/ExtractAPI/ExtractAPIConsumer.cpp   |  84 +-
 clang/test/ExtractAPI/macros.c| 756 --
 4 files changed, 382 insertions(+), 466 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 535da90b98284b..4ac744459031eb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -411,9 +411,9 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a macro.
   ///
   /// \param Name name of the macro.
-  /// \param MD the associated MacroDirective.
+  /// \param MI the associated MacroInfo.
   static DeclarationFragments getFragmentsForMacro(StringRef Name,
-   const MacroDirective *MD);
+   const MacroInfo *MI);
 
   /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
   static DeclarationFragments
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 6b85c7db90349e..d77bb1d424f7cf 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1327,14 +1327,12 @@ 
DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization(
 
 DeclarationFragments
 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
-  const MacroDirective *MD) {
+  const MacroInfo *MI) {
   DeclarationFragments Fragments;
   Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
   .appendSpace();
   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
 
-  auto *MI = MD->getMacroInfo();
-
   if (MI->isFunctionLike()) {
 Fragments.append("(", DeclarationFragments::FragmentKind::Text);
 unsigned numParameters = MI->getNumParams();
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp 
b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index d6335854cbf262..b23a62267651c8 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -286,78 +286,54 @@ class MacroCallback : public PPCallbacks {
   MacroCallback(const SourceManager &SM, APISet &API, Preprocessor &PP)
   : SM(SM), API(API), PP(PP) {}
 
-  void MacroDefined(const Token &MacroNameToken,
-const Macr

[clang] [clang][ExtractAPI] Fix quirks in interaction with submodules (PR #105868)

2024-08-23 Thread Daniel Grumberg via cfe-commits

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

Extension SGFs require the module system to be enabled in order to discover 
which module defines the extended external type.
This patch ensures the following:
- Associate symbols with their top level module name,
- Ensure we don't drop macro definitions that came from a submodule but that 
should be included in the SGF output.

>From b687c9512b748ee593eedd5e06d04d2a40197ec3 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 23 Aug 2024 10:02:42 +0100
Subject: [PATCH 1/4] [clang][ExtractAPI] Use top level module name for
 tracking which module a symbol came from

rdar://123020565
---
 clang/include/clang/ExtractAPI/ExtractAPIVisitor.h   | 2 +-
 clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 67659f5a25037c..b09b8b44d9abaa 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -213,7 +213,7 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 
   StringRef getOwningModuleName(const Decl &D) {
 if (auto *OwningModule = D.getImportedOwningModule())
-  return OwningModule->Name;
+  return OwningModule->getTopLevelModule()->Name;
 
 return {};
   }
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 1bce9c59b19791..54124ddbb2f58a 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -928,8 +928,8 @@ bool SymbolGraphSerializer::traverseObjCCategoryRecord(
 return true;
 
   auto *CurrentModule = ModuleForCurrentSymbol;
-  if (Record->isExtendingExternalModule())
-ModuleForCurrentSymbol = &ExtendedModules[Record->Interface.Source];
+  if (auto ModuleExtendedByRecord= Record->getExtendedExternalModule())
+ModuleForCurrentSymbol = &ExtendedModules[*ModuleExtendedByRecord];
 
   if (!walkUpFromObjCCategoryRecord(Record))
 return false;

>From dc061de96ede86df0afdb01bde797c3965760ebb Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 23 Aug 2024 18:16:50 +0100
Subject: [PATCH 2/4] [clang][ExtractAPI] Fix macro detection code to work with
 modules enabled

Change macro detection from using `MacroDefined` callback to iterating
over all visible macros in `EndOfMainFile` callback. This way macros
that came from an ASTFile are taken into account.
---
 .../clang/ExtractAPI/DeclarationFragments.h   |   4 +-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |   4 +-
 clang/lib/ExtractAPI/ExtractAPIConsumer.cpp   |  84 +-
 clang/test/ExtractAPI/macros.c| 756 --
 4 files changed, 382 insertions(+), 466 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 535da90b98284b..4ac744459031eb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -411,9 +411,9 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a macro.
   ///
   /// \param Name name of the macro.
-  /// \param MD the associated MacroDirective.
+  /// \param MI the associated MacroInfo.
   static DeclarationFragments getFragmentsForMacro(StringRef Name,
-   const MacroDirective *MD);
+   const MacroInfo *MI);
 
   /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
   static DeclarationFragments
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 6b85c7db90349e..d77bb1d424f7cf 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1327,14 +1327,12 @@ 
DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization(
 
 DeclarationFragments
 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
-  const MacroDirective *MD) {
+  const MacroInfo *MI) {
   DeclarationFragments Fragments;
   Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
   .appendSpace();
   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
 
-  auto *MI = MD->getMacroInfo();
-
   if (MI->isFunctionLike()) {
 Fragments.append("(", DeclarationFragments::FragmentKind::Text);
 unsigned numParameters = MI->getNumParams();
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp 
b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index d6335854cbf262..b23a62267651c8 100644
--- a/clang/lib/ExtractAPI/

[clang] Reenable anon structs (PR #104922)

2024-08-20 Thread Daniel Grumberg via cfe-commits

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


[clang] b18b454 - Revert "[clang][ExtractAPI] Stop dropping fields of nested anonymous record types when they aren't attached to variable declaration (#104600)"

2024-08-19 Thread Daniel Grumberg via cfe-commits

Author: Daniel Grumberg
Date: 2024-08-19T16:06:43+01:00
New Revision: b18b4547f1bfaf6da37b29440a96176e807c2e6c

URL: 
https://github.com/llvm/llvm-project/commit/b18b4547f1bfaf6da37b29440a96176e807c2e6c
DIFF: 
https://github.com/llvm/llvm-project/commit/b18b4547f1bfaf6da37b29440a96176e807c2e6c.diff

LOG: Revert "[clang][ExtractAPI] Stop dropping fields of nested anonymous 
record types when they aren't attached to variable declaration (#104600)"

This reverts commit c60da1a271a6bb271e7703b2f7c71fbece67ab78.

Added: 


Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
clang/test/ExtractAPI/anonymous_record_no_typedef.c

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 188e35b72117b5..bf291074fd0614 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -19,13 +19,21 @@
 #define LLVM_CLANG_EXTRACTAPI_API_H
 
 #include "clang/AST/Availability.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -320,8 +328,6 @@ class RecordContext {
   /// chain.
   void stealRecordChain(RecordContext &Other);
 
-  void removeFromRecordChain(APIRecord *Record);
-
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -1420,15 +1426,10 @@ class APISet {
   typename std::enable_if_t, RecordTy> *
   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
 
-  auto getTopLevelRecords() const {
-return llvm::iterator_range(
-TopLevelRecords);
+  ArrayRef getTopLevelRecords() const {
+return TopLevelRecords;
   }
 
-  void removeRecord(StringRef USR);
-
-  void removeRecord(APIRecord *Record);
-
   APISet(const llvm::Triple &Target, Language Lang,
  const std::string &ProductName)
   : Target(Target), Lang(Lang), ProductName(ProductName) {}
@@ -1455,7 +1456,7 @@ class APISet {
   // lives in the BumpPtrAllocator.
   using APIRecordStoredPtr = std::unique_ptr;
   llvm::DenseMap USRBasedLookupTable;
-  llvm::SmallPtrSet TopLevelRecords;
+  std::vector TopLevelRecords;
 
 public:
   const std::string ProductName;
@@ -1481,7 +1482,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
 dyn_cast_if_present(Record->Parent.Record))
   ParentContext->addToRecordChain(Record);
 else
-  TopLevelRecords.insert(Record);
+  TopLevelRecords.push_back(Record);
   } else {
 Record = dyn_cast(Result.first->second.get());
   }

diff  --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 8d9ac062034511..1b27027621666a 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -23,11 +23,13 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/ExtractAPI/API.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include 
@@ -38,8 +40,6 @@ namespace impl {
 
 template 
 class ExtractAPIVisitorBase : public RecursiveASTVisitor {
-  using Base = RecursiveASTVisitor;
-
 protected:
   ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
   : Context(Context), API(API) {}
@@ -81,10 +81,8 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 
   bool VisitNamespaceDecl(const NamespaceDecl *Decl);
 
-  bool TraverseRecordDecl(RecordDecl *Decl);
   bool VisitRecordDecl(const RecordDecl *Decl);
 
-  bool TraverseCXXRecordDecl(CXXRecordDecl *Decl);
   bool VisitCXXRecordDecl(const CXXRecordDecl *Decl);
 
   bool VisitCXXMethodDecl(const CXXMethodDecl *Decl);
@@ -242,7 +240,7 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 
   bool isEmbeddedInVarDeclarator(const TagDecl &D) {
 return D.getName().empty() && getTypedefName(&D).empty() &&
-   D.isEmbeddedInDeclarator() && !D.isFreeStanding();
+   

[clang] [clang][ExtractAPI] Stop dropping fields of nested anonymous record types when they aren't attached to variable declaration (PR #104600)

2024-08-19 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Stop dropping fields of nested anonymous record types when they aren't attached to variable declaration (PR #104600)

2024-08-19 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/104600

>From 8e3909ecb1bfe6aec6344cd89cbe1798d6cde7da Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 15 Aug 2024 17:42:02 +0100
Subject: [PATCH 1/4] [clang][ExtractAPI] Implement Record removal from APISet

rdar://128092236
---
 clang/include/clang/ExtractAPI/API.h | 24 ++--
 clang/lib/ExtractAPI/API.cpp | 57 +++-
 2 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index bf291074fd0614..3b36dfe0325b9b 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -19,21 +19,13 @@
 #define LLVM_CLANG_EXTRACTAPI_API_H
 
 #include "clang/AST/Availability.h"
-#include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclObjC.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -328,6 +320,8 @@ class RecordContext {
   /// chain.
   void stealRecordChain(RecordContext &Other);
 
+  void removeFromRecordChain(APIRecord *Record);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -1426,10 +1420,14 @@ class APISet {
   typename std::enable_if_t, RecordTy> *
   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
 
-  ArrayRef getTopLevelRecords() const {
-return TopLevelRecords;
+  auto getTopLevelRecords() const {
+return 
llvm::iterator_range(TopLevelRecords);
   }
 
+  void removeRecord(StringRef USR);
+
+  void removeRecord(APIRecord *Record);
+
   APISet(const llvm::Triple &Target, Language Lang,
  const std::string &ProductName)
   : Target(Target), Lang(Lang), ProductName(ProductName) {}
@@ -1456,7 +1454,7 @@ class APISet {
   // lives in the BumpPtrAllocator.
   using APIRecordStoredPtr = std::unique_ptr;
   llvm::DenseMap USRBasedLookupTable;
-  std::vector TopLevelRecords;
+  llvm::SmallPtrSet TopLevelRecords;
 
 public:
   const std::string ProductName;
@@ -1482,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
 dyn_cast_if_present(Record->Parent.Record))
   ParentContext->addToRecordChain(Record);
 else
-  TopLevelRecords.push_back(Record);
+  TopLevelRecords.insert(Record);
   } else {
 Record = dyn_cast(Result.first->second.get());
   }
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index ab1108f663deac..48d8bb7f600630 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -13,8 +13,6 @@
 
//===--===//
 
 #include "clang/ExtractAPI/API.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
@@ -60,6 +58,10 @@ bool RecordContext::IsWellFormed() const {
 
 void RecordContext::stealRecordChain(RecordContext &Other) {
   assert(IsWellFormed());
+  // Other's record chain is empty, nothing to do
+  if (Other.First == nullptr && Other.Last == nullptr)
+return;
+
   // If we don't have an empty chain append Other's chain into ours.
   if (First)
 Last->NextInContext = Other.First;
@@ -68,6 +70,9 @@ void RecordContext::stealRecordChain(RecordContext &Other) {
 
   Last = Other.Last;
 
+  for (auto *StolenRecord = Other.First; StolenRecord != nullptr; StolenRecord 
= StolenRecord->getNextInContext())
+StolenRecord->Parent = SymbolReference(cast(this));
+
   // Delete Other's chain to ensure we don't accidentally traverse it.
   Other.First = nullptr;
   Other.Last = nullptr;
@@ -85,6 +90,22 @@ void RecordContext::addToRecordChain(APIRecord *Record) 
const {
   Last = Record;
 }
 
+void RecordContext::removeFromRecordChain(APIRecord *Record) {
+  APIRecord *Prev = nullptr;
+  for (APIRecord *Curr = First; Curr != Record; Curr = Curr->NextInContext)
+Prev = Curr;
+
+  if (Prev)
+Prev->NextInContext = Record->NextInContext;
+  else
+First = Record->NextInContext;
+
+  if (Last == Record)
+Last = Prev;
+
+  Record->NextInContext = nullptr;
+}
+
 APIRecord *APISet::findRecordForUSR(StringRef USR) const {
   if (USR.empty())
 return nullptr;
@@ -114,6 +135,38 @@ SymbolReference APISet::createSymbolReference(StringRef 
Name, StringRef USR,
   return SymbolReference(copyString(Name), copyString(USR), 
copyString(Source));
 }
 
+
+void APISet::removeRecord

[clang] [clang][ExtractAPI] Stop dropping fields of nested anonymous record types when they aren't attached to variable declaration (PR #104600)

2024-08-16 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/104600

>From 61b8014d418867e0108bf4513227d9a8fdad63f8 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 15 Aug 2024 17:42:02 +0100
Subject: [PATCH 1/4] [clang][ExtractAPI] Implement Record removal from APISet

rdar://128092236
---
 clang/include/clang/ExtractAPI/API.h | 24 ++--
 clang/lib/ExtractAPI/API.cpp | 57 +++-
 2 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index bf291074fd0614..3b36dfe0325b9b 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -19,21 +19,13 @@
 #define LLVM_CLANG_EXTRACTAPI_API_H
 
 #include "clang/AST/Availability.h"
-#include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclObjC.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -328,6 +320,8 @@ class RecordContext {
   /// chain.
   void stealRecordChain(RecordContext &Other);
 
+  void removeFromRecordChain(APIRecord *Record);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -1426,10 +1420,14 @@ class APISet {
   typename std::enable_if_t, RecordTy> *
   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
 
-  ArrayRef getTopLevelRecords() const {
-return TopLevelRecords;
+  auto getTopLevelRecords() const {
+return 
llvm::iterator_range(TopLevelRecords);
   }
 
+  void removeRecord(StringRef USR);
+
+  void removeRecord(APIRecord *Record);
+
   APISet(const llvm::Triple &Target, Language Lang,
  const std::string &ProductName)
   : Target(Target), Lang(Lang), ProductName(ProductName) {}
@@ -1456,7 +1454,7 @@ class APISet {
   // lives in the BumpPtrAllocator.
   using APIRecordStoredPtr = std::unique_ptr;
   llvm::DenseMap USRBasedLookupTable;
-  std::vector TopLevelRecords;
+  llvm::SmallPtrSet TopLevelRecords;
 
 public:
   const std::string ProductName;
@@ -1482,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
 dyn_cast_if_present(Record->Parent.Record))
   ParentContext->addToRecordChain(Record);
 else
-  TopLevelRecords.push_back(Record);
+  TopLevelRecords.insert(Record);
   } else {
 Record = dyn_cast(Result.first->second.get());
   }
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index ab1108f663deac..48d8bb7f600630 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -13,8 +13,6 @@
 
//===--===//
 
 #include "clang/ExtractAPI/API.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
@@ -60,6 +58,10 @@ bool RecordContext::IsWellFormed() const {
 
 void RecordContext::stealRecordChain(RecordContext &Other) {
   assert(IsWellFormed());
+  // Other's record chain is empty, nothing to do
+  if (Other.First == nullptr && Other.Last == nullptr)
+return;
+
   // If we don't have an empty chain append Other's chain into ours.
   if (First)
 Last->NextInContext = Other.First;
@@ -68,6 +70,9 @@ void RecordContext::stealRecordChain(RecordContext &Other) {
 
   Last = Other.Last;
 
+  for (auto *StolenRecord = Other.First; StolenRecord != nullptr; StolenRecord 
= StolenRecord->getNextInContext())
+StolenRecord->Parent = SymbolReference(cast(this));
+
   // Delete Other's chain to ensure we don't accidentally traverse it.
   Other.First = nullptr;
   Other.Last = nullptr;
@@ -85,6 +90,22 @@ void RecordContext::addToRecordChain(APIRecord *Record) 
const {
   Last = Record;
 }
 
+void RecordContext::removeFromRecordChain(APIRecord *Record) {
+  APIRecord *Prev = nullptr;
+  for (APIRecord *Curr = First; Curr != Record; Curr = Curr->NextInContext)
+Prev = Curr;
+
+  if (Prev)
+Prev->NextInContext = Record->NextInContext;
+  else
+First = Record->NextInContext;
+
+  if (Last == Record)
+Last = Prev;
+
+  Record->NextInContext = nullptr;
+}
+
 APIRecord *APISet::findRecordForUSR(StringRef USR) const {
   if (USR.empty())
 return nullptr;
@@ -114,6 +135,38 @@ SymbolReference APISet::createSymbolReference(StringRef 
Name, StringRef USR,
   return SymbolReference(copyString(Name), copyString(USR), 
copyString(Source));
 }
 
+
+void APISet::removeRecord

[clang] [clang][ExtractAPI] Stop dropping fields of nested anonymous record types when they aren't attached to variable declaration (PR #104600)

2024-08-16 Thread Daniel Grumberg via cfe-commits

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

- Introduce primitives for removing records from `APISet` and managing the 
record chain of `RecordContext`
- Detect nested anonymous record types and remove them from the `APISet` after 
they have been fully traversed and transfer ownership of child records to the 
parent context (if any)

>From 61b8014d418867e0108bf4513227d9a8fdad63f8 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 15 Aug 2024 17:42:02 +0100
Subject: [PATCH 1/3] [clang][ExtractAPI] Implement Record removal from APISet

rdar://128092236
---
 clang/include/clang/ExtractAPI/API.h | 24 ++--
 clang/lib/ExtractAPI/API.cpp | 57 +++-
 2 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index bf291074fd0614..3b36dfe0325b9b 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -19,21 +19,13 @@
 #define LLVM_CLANG_EXTRACTAPI_API_H
 
 #include "clang/AST/Availability.h"
-#include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclObjC.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
 #include "clang/ExtractAPI/DeclarationFragments.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include 
 #include 
@@ -328,6 +320,8 @@ class RecordContext {
   /// chain.
   void stealRecordChain(RecordContext &Other);
 
+  void removeFromRecordChain(APIRecord *Record);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -1426,10 +1420,14 @@ class APISet {
   typename std::enable_if_t, RecordTy> *
   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
 
-  ArrayRef getTopLevelRecords() const {
-return TopLevelRecords;
+  auto getTopLevelRecords() const {
+return 
llvm::iterator_range(TopLevelRecords);
   }
 
+  void removeRecord(StringRef USR);
+
+  void removeRecord(APIRecord *Record);
+
   APISet(const llvm::Triple &Target, Language Lang,
  const std::string &ProductName)
   : Target(Target), Lang(Lang), ProductName(ProductName) {}
@@ -1456,7 +1454,7 @@ class APISet {
   // lives in the BumpPtrAllocator.
   using APIRecordStoredPtr = std::unique_ptr;
   llvm::DenseMap USRBasedLookupTable;
-  std::vector TopLevelRecords;
+  llvm::SmallPtrSet TopLevelRecords;
 
 public:
   const std::string ProductName;
@@ -1482,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
 dyn_cast_if_present(Record->Parent.Record))
   ParentContext->addToRecordChain(Record);
 else
-  TopLevelRecords.push_back(Record);
+  TopLevelRecords.insert(Record);
   } else {
 Record = dyn_cast(Result.first->second.get());
   }
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index ab1108f663deac..48d8bb7f600630 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -13,8 +13,6 @@
 
//===--===//
 
 #include "clang/ExtractAPI/API.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
@@ -60,6 +58,10 @@ bool RecordContext::IsWellFormed() const {
 
 void RecordContext::stealRecordChain(RecordContext &Other) {
   assert(IsWellFormed());
+  // Other's record chain is empty, nothing to do
+  if (Other.First == nullptr && Other.Last == nullptr)
+return;
+
   // If we don't have an empty chain append Other's chain into ours.
   if (First)
 Last->NextInContext = Other.First;
@@ -68,6 +70,9 @@ void RecordContext::stealRecordChain(RecordContext &Other) {
 
   Last = Other.Last;
 
+  for (auto *StolenRecord = Other.First; StolenRecord != nullptr; StolenRecord 
= StolenRecord->getNextInContext())
+StolenRecord->Parent = SymbolReference(cast(this));
+
   // Delete Other's chain to ensure we don't accidentally traverse it.
   Other.First = nullptr;
   Other.Last = nullptr;
@@ -85,6 +90,22 @@ void RecordContext::addToRecordChain(APIRecord *Record) 
const {
   Last = Record;
 }
 
+void RecordContext::removeFromRecordChain(APIRecord *Record) {
+  APIRecord *Prev = nullptr;
+  for (APIRecord *Curr = First; Curr != Record; Curr = Curr->NextInContext)
+Prev = Curr;
+
+  if (Prev)
+Prev->NextInContext = Record->NextInContext;
+  else
+First = Record->NextInContext;
+
+  if (Last == Record)
+Last = Prev;
+
+  Record->NextInContext = nullptr;
+}
+
 APIRecord *APISet::find

[clang] [clang][ExtractAPI] Emit environment component of target triple in SGF (PR #103273)

2024-08-15 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-15 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-14 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/103040

>From cd38c476336ea90e4d080638d028dda203b52ac4 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 13 Aug 2024 11:30:18 +0100
Subject: [PATCH 1/5] [clang][ExtractAPI] Compute inherited availability
 information

Additionally this computes availability information for all platforms
ahead of possibly introducing a flag to enable this behavior.

rdar://123513706
---
 clang/include/clang/AST/Availability.h|   4 +
 clang/lib/AST/Availability.cpp| 100 ++--
 .../Serialization/SymbolGraphSerializer.cpp   |  31 ++--
 .../test/ExtractAPI/inherited_availability.m  | 149 ++
 4 files changed, 254 insertions(+), 30 deletions(-)
 create mode 100644 clang/test/ExtractAPI/inherited_availability.m

diff --git a/clang/include/clang/AST/Availability.h 
b/clang/include/clang/AST/Availability.h
index 26ae622e5b4496..60ca1383f0a44e 100644
--- a/clang/include/clang/AST/Availability.h
+++ b/clang/include/clang/AST/Availability.h
@@ -97,6 +97,10 @@ struct AvailabilityInfo {
 return UnconditionallyUnavailable;
   }
 
+  /// Augments the existing information with additional constraints provided by
+  /// \c Other.
+  void mergeWith(AvailabilityInfo Other);
+
   AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
VersionTuple O, bool U, bool UD, bool UU)
   : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
diff --git a/clang/lib/AST/Availability.cpp b/clang/lib/AST/Availability.cpp
index 238359a2dedfcf..376a625b41817a 100644
--- a/clang/lib/AST/Availability.cpp
+++ b/clang/lib/AST/Availability.cpp
@@ -16,33 +16,101 @@
 #include "clang/AST/Decl.h"
 #include "clang/Basic/TargetInfo.h"
 
-namespace clang {
+namespace {
+
+struct AvailabilitySet {
+  llvm::SmallVector Availabilities;
+  bool UnconditionallyDeprecated = false;
+  bool UnconditionallyUnavailable = false;
 
-AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *Decl) {
-  ASTContext &Context = Decl->getASTContext();
-  StringRef PlatformName = Context.getTargetInfo().getPlatformName();
-  AvailabilityInfo Availability;
+  void insert(clang::AvailabilityInfo &&Availability) {
+auto *Found = getForPlatform(Availability.Domain);
+if (Found)
+  Found->mergeWith(std::move(Availability));
+else
+  Availabilities.emplace_back(std::move(Availability));
+  }
+
+  clang::AvailabilityInfo *getForPlatform(llvm::StringRef Domain) {
+auto *It = llvm::find_if(Availabilities,
+ [Domain](const clang::AvailabilityInfo &Info) {
+   return Domain.compare(Info.Domain) == 0;
+ });
+return It == Availabilities.end() ? nullptr : It;
+  }
+};
 
+static void createInfoForDecl(const clang::Decl *Decl,
+  AvailabilitySet &Availabilities) {
   // Collect availability attributes from all redeclarations.
   for (const auto *RD : Decl->redecls()) {
-for (const auto *A : RD->specific_attrs()) {
-  if (A->getPlatform()->getName() != PlatformName)
-continue;
-  Availability = AvailabilityInfo(
+for (const auto *A : RD->specific_attrs()) {
+  Availabilities.insert(clang::AvailabilityInfo(
   A->getPlatform()->getName(), A->getIntroduced(), A->getDeprecated(),
-  A->getObsoleted(), A->getUnavailable(), false, false);
-  break;
+  A->getObsoleted(), A->getUnavailable(), false, false));
 }
 
-if (const auto *A = RD->getAttr())
+if (const auto *A = RD->getAttr())
   if (!A->isImplicit())
-Availability.UnconditionallyUnavailable = true;
+Availabilities.UnconditionallyUnavailable = true;
 
-if (const auto *A = RD->getAttr())
+if (const auto *A = RD->getAttr())
   if (!A->isImplicit())
-Availability.UnconditionallyDeprecated = true;
+Availabilities.UnconditionallyDeprecated = true;
+  }
+}
+
+} // namespace
+
+namespace clang {
+
+void AvailabilityInfo::mergeWith(AvailabilityInfo Other) {
+  if (isDefault() && Other.isDefault())
+return;
+
+  if (Domain.empty())
+Domain = Other.Domain;
+
+  UnconditionallyUnavailable |= Other.UnconditionallyUnavailable;
+  UnconditionallyDeprecated |= Other.UnconditionallyDeprecated;
+  Unavailable |= Other.Unavailable;
+
+  Introduced = std::max(Introduced, Other.Introduced);
+
+  // Default VersionTuple is 0.0.0 so if both are non default let's pick the
+  // smallest version number, otherwise select the one that is non-zero if 
there
+  // is one.
+  if (!Deprecated.empty() && !Other.Deprecated.empty())
+Deprecated = std::min(Deprecated, Other.Deprecated);
+  else
+Deprecated = std::max(Deprecated, Other.Deprecated);
+
+  if (!Obsoleted.empty() && !Other.Obsoleted.empty())
+Obsoleted = std::min(Obsoleted, Other.Obsoleted);
+  else
+Obsoleted = std::max(Obsoleted, Other.Obsoleted);
+}
+
+Availabili

[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-14 Thread Daniel Grumberg via cfe-commits


@@ -16,33 +16,101 @@
 #include "clang/AST/Decl.h"
 #include "clang/Basic/TargetInfo.h"
 
-namespace clang {
+namespace {
+
+struct AvailabilitySet {
+  llvm::SmallVector Availabilities;
+  bool UnconditionallyDeprecated = false;
+  bool UnconditionallyUnavailable = false;
 
-AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *Decl) {
-  ASTContext &Context = Decl->getASTContext();
-  StringRef PlatformName = Context.getTargetInfo().getPlatformName();
-  AvailabilityInfo Availability;
+  void insert(clang::AvailabilityInfo &&Availability) {
+auto *Found = getForPlatform(Availability.Domain);
+if (Found)
+  Found->mergeWith(std::move(Availability));
+else
+  Availabilities.emplace_back(std::move(Availability));
+  }
+
+  clang::AvailabilityInfo *getForPlatform(llvm::StringRef Domain) {

daniel-grumberg wrote:

The semantic is that you get a reference of the thing inside the Availabilities 
vector if it exist (this method is used by `insert` and not just 
`AvailabilityInfo::createFromDecl`), to express that with 
`std::optional` which doesn't exist.

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


[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-14 Thread Daniel Grumberg via cfe-commits


@@ -0,0 +1,149 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing -triple arm64-apple-macosx \
+// RUN:   -x objective-c-header %s -o %t/output.symbols.json -verify
+
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix A
+__attribute__((availability(macos, introduced=9.0, deprecated=12.0, 
obsoleted=20.0)))
+@interface A

daniel-grumberg wrote:

It walks DeclContext's upwards to find one to compute the most restrictive 
information. If the are no other annotations for that platform walking upwards 
then it is just the one in the availability annotation. I realized that the 
existing availability test case doesn't cover this, thanks for pointing it out 
I will add a test to validate this behavior.

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


[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-14 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

> > Additionally this computes availability information for all platforms ahead
> 
> Can you add a test for this?

The behavior is not exposed yet so I can't add a test, will do when I start 
exposing the behavior.

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


[clang] [clang][ExtractAPI] Emit environment component of target triple in SGF (PR #103273)

2024-08-13 Thread Daniel Grumberg via cfe-commits

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

rdar://133533830

>From 6c9fdf64b14c14db00fbf4ba8ec4103b14ddb72d Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 13 Aug 2024 16:09:58 +0100
Subject: [PATCH] [clang][ExtractAPI] Emit environment component of target
 triple in SGF

rdar://133533830
---
 .../Serialization/SymbolGraphSerializer.cpp   |  4 
 .../test/ExtractAPI/platform-serialization.c  | 20 +++
 2 files changed, 24 insertions(+)
 create mode 100644 clang/test/ExtractAPI/platform-serialization.c

diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 6e56ee5b573f66..647c8659639f35 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -104,6 +104,10 @@ Object serializePlatform(const Triple &T) {
   Object Platform;
   Platform["architecture"] = T.getArchName();
   Platform["vendor"] = T.getVendorName();
+
+  if (!T.getEnvironmentName().empty())
+Platform["environment"] = T.getEnvironmentName();
+
   Platform["operatingSystem"] = serializeOperatingSystem(T);
   return Platform;
 }
diff --git a/clang/test/ExtractAPI/platform-serialization.c 
b/clang/test/ExtractAPI/platform-serialization.c
new file mode 100644
index 00..6d6a13f085cd9d
--- /dev/null
+++ b/clang/test/ExtractAPI/platform-serialization.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -extract-api --pretty-sgf -triple 
arm64-apple-ios17.1-macabi \
+// RUN:   -x c-header %s -verify -o - | FileCheck %s
+
+int a;
+
+// CHECK:  "platform": {
+// CHECK-NEXT:   "architecture": "arm64",
+// CHECK-NEXT:   "environment": "macabi",
+// CHECK-NEXT:   "operatingSystem": {
+// CHECK-NEXT: "minimumVersion": {
+// CHECK-NEXT:   "major": 14,
+// CHECK-NEXT:   "minor": 0,
+// CHECK-NEXT:   "patch": 0
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "ios"
+// CHECK-NEXT:   },
+// CHECK-NEXT:   "vendor": "apple"
+// CHECK-NEXT: }
+
+// expected-no-diagnostics

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Compute inherited availability information (PR #103040)

2024-08-13 Thread Daniel Grumberg via cfe-commits

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

Additionally this computes availability information for all platforms ahead of 
possibly introducing a flag to enable this behavior.

rdar://123513706

>From cd38c476336ea90e4d080638d028dda203b52ac4 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 13 Aug 2024 11:30:18 +0100
Subject: [PATCH] [clang][ExtractAPI] Compute inherited availability
 information

Additionally this computes availability information for all platforms
ahead of possibly introducing a flag to enable this behavior.

rdar://123513706
---
 clang/include/clang/AST/Availability.h|   4 +
 clang/lib/AST/Availability.cpp| 100 ++--
 .../Serialization/SymbolGraphSerializer.cpp   |  31 ++--
 .../test/ExtractAPI/inherited_availability.m  | 149 ++
 4 files changed, 254 insertions(+), 30 deletions(-)
 create mode 100644 clang/test/ExtractAPI/inherited_availability.m

diff --git a/clang/include/clang/AST/Availability.h 
b/clang/include/clang/AST/Availability.h
index 26ae622e5b4496..60ca1383f0a44e 100644
--- a/clang/include/clang/AST/Availability.h
+++ b/clang/include/clang/AST/Availability.h
@@ -97,6 +97,10 @@ struct AvailabilityInfo {
 return UnconditionallyUnavailable;
   }
 
+  /// Augments the existing information with additional constraints provided by
+  /// \c Other.
+  void mergeWith(AvailabilityInfo Other);
+
   AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
VersionTuple O, bool U, bool UD, bool UU)
   : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
diff --git a/clang/lib/AST/Availability.cpp b/clang/lib/AST/Availability.cpp
index 238359a2dedfcf..376a625b41817a 100644
--- a/clang/lib/AST/Availability.cpp
+++ b/clang/lib/AST/Availability.cpp
@@ -16,33 +16,101 @@
 #include "clang/AST/Decl.h"
 #include "clang/Basic/TargetInfo.h"
 
-namespace clang {
+namespace {
+
+struct AvailabilitySet {
+  llvm::SmallVector Availabilities;
+  bool UnconditionallyDeprecated = false;
+  bool UnconditionallyUnavailable = false;
 
-AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *Decl) {
-  ASTContext &Context = Decl->getASTContext();
-  StringRef PlatformName = Context.getTargetInfo().getPlatformName();
-  AvailabilityInfo Availability;
+  void insert(clang::AvailabilityInfo &&Availability) {
+auto *Found = getForPlatform(Availability.Domain);
+if (Found)
+  Found->mergeWith(std::move(Availability));
+else
+  Availabilities.emplace_back(std::move(Availability));
+  }
+
+  clang::AvailabilityInfo *getForPlatform(llvm::StringRef Domain) {
+auto *It = llvm::find_if(Availabilities,
+ [Domain](const clang::AvailabilityInfo &Info) {
+   return Domain.compare(Info.Domain) == 0;
+ });
+return It == Availabilities.end() ? nullptr : It;
+  }
+};
 
+static void createInfoForDecl(const clang::Decl *Decl,
+  AvailabilitySet &Availabilities) {
   // Collect availability attributes from all redeclarations.
   for (const auto *RD : Decl->redecls()) {
-for (const auto *A : RD->specific_attrs()) {
-  if (A->getPlatform()->getName() != PlatformName)
-continue;
-  Availability = AvailabilityInfo(
+for (const auto *A : RD->specific_attrs()) {
+  Availabilities.insert(clang::AvailabilityInfo(
   A->getPlatform()->getName(), A->getIntroduced(), A->getDeprecated(),
-  A->getObsoleted(), A->getUnavailable(), false, false);
-  break;
+  A->getObsoleted(), A->getUnavailable(), false, false));
 }
 
-if (const auto *A = RD->getAttr())
+if (const auto *A = RD->getAttr())
   if (!A->isImplicit())
-Availability.UnconditionallyUnavailable = true;
+Availabilities.UnconditionallyUnavailable = true;
 
-if (const auto *A = RD->getAttr())
+if (const auto *A = RD->getAttr())
   if (!A->isImplicit())
-Availability.UnconditionallyDeprecated = true;
+Availabilities.UnconditionallyDeprecated = true;
+  }
+}
+
+} // namespace
+
+namespace clang {
+
+void AvailabilityInfo::mergeWith(AvailabilityInfo Other) {
+  if (isDefault() && Other.isDefault())
+return;
+
+  if (Domain.empty())
+Domain = Other.Domain;
+
+  UnconditionallyUnavailable |= Other.UnconditionallyUnavailable;
+  UnconditionallyDeprecated |= Other.UnconditionallyDeprecated;
+  Unavailable |= Other.Unavailable;
+
+  Introduced = std::max(Introduced, Other.Introduced);
+
+  // Default VersionTuple is 0.0.0 so if both are non default let's pick the
+  // smallest version number, otherwise select the one that is non-zero if 
there
+  // is one.
+  if (!Deprecated.empty() && !Other.Deprecated.empty())
+Deprecated = std::min(Deprecated, Other.Deprecated);
+  else
+Deprecated = std::max(Deprecated, Other.Deprecated);
+
+  if (!Obsoleted.empty() && !Other.Obsol

[clang] [clang][ExtractAPI][NFC] Remove some nullptr dereference problems (PR #98914)

2024-07-16 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI][NFC] Remove some nullptr dereference problems (PR #98914)

2024-07-15 Thread Daniel Grumberg via cfe-commits

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

A places try to get a NamedDecl's name using getName when it isn't a simple 
identifier, migrate these areas to getNameAsString.

rdar://125315602

>From 20a72b3170d284f1f984d1dc7c868fe5632df510 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 9 Jul 2024 17:40:10 +0100
Subject: [PATCH] [clang][ExtractAPI][NFC] Remove some nullptr dereference
 problems

A places try to get a NamedDecl's name using getName when it isn't a
simple identifier, migrate these areas to getNameAsString.

rdar://125315602
---
 .../clang/ExtractAPI/ExtractAPIVisitor.h  | 51 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  8 ++-
 2 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 76d7fd798bed3..1b27027621666 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -175,22 +175,25 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
   // skip classes not inherited as public
   if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
 continue;
-  SymbolReference BaseClass;
-  if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
-BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
-if (auto *TTPTD = BaseSpecifier.getType()
-  ->getAs()
-  ->getDecl()) {
-  SmallString<128> USR;
-  index::generateUSRForDecl(TTPTD, USR);
-  BaseClass.USR = API.copyString(USR);
-  BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
-}
+  if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
+Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
   } else {
-BaseClass = createSymbolReferenceForDecl(
-*BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl());
+SymbolReference BaseClass;
+BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
+Decl->getASTContext().getPrintingPolicy()));
+
+if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
+  if (auto *TTPTD = BaseSpecifier.getType()
+->getAs()
+->getDecl()) {
+SmallString<128> USR;
+index::generateUSRForDecl(TTPTD, USR);
+BaseClass.USR = API.copyString(USR);
+BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
+  }
+}
+Bases.emplace_back(BaseClass);
   }
-  Bases.emplace_back(BaseClass);
 }
 return Bases;
   }
@@ -352,7 +355,7 @@ bool ExtractAPIVisitorBase::VisitFunctionDecl(
 return true;
 
   // Collect symbol information.
-  StringRef Name = Decl->getName();
+  auto Name = Decl->getNameAsString();
   SmallString<128> USR;
   index::generateUSRForDecl(Decl, USR);
   PresumedLoc Loc =
@@ -666,8 +669,8 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl(
   if (FunctionTemplateDecl *TemplateDecl =
   Decl->getDescribedFunctionTemplate()) {
 API.createRecord(
-USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
-AvailabilityInfo::createFromDecl(Decl), Comment,
+USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
+Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(
 TemplateDecl),
 SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Decl),
@@ -675,8 +678,8 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl(
 Template(TemplateDecl), isInSystemHeader(Decl));
   } else if (Decl->getTemplateSpecializationInfo())
 API.createRecord(
-USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
-AvailabilityInfo::createFromDecl(Decl), Comment,
+USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
+Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
 DeclarationFragmentsBuilder::
 getFragmentsForFunctionTemplateSpecialization(Decl),
 SubHeading, Signature, Access, isInSystemHeader(Decl));
@@ -688,14 +691,14 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl(
 SubHeading, Signature, Access, isInSystemHeader(Decl));
   else if (Decl->isStatic())
 API.createRecord(
-USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
-AvailabilityInfo::createFromDecl(Decl), Comment,
+USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
+Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
 DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), 
SubHeadi

[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)

2024-06-10 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

Thanks for looking at these, I think it would be best to try and leverage move 
semantics where possible if we are going to change this code.

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


[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)

2024-06-10 Thread Daniel Grumberg via cfe-commits


@@ -240,7 +241,7 @@ class DeclarationFragments {
 
 class AccessControl {
 public:
-  AccessControl(std::string Access) : Access(Access) {}

daniel-grumberg wrote:

Again I would prefer if we kept the value semantic ones and use `std::move`

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


[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)

2024-06-10 Thread Daniel Grumberg via cfe-commits


@@ -199,7 +199,8 @@ class DeclarationFragments {
 return *this;
   }
 
-  DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {

daniel-grumberg wrote:

I would prefer to keep the value semantics version and instead move assign the 
value, that way callers can move the string in and avoid any copies.

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


[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)

2024-05-29 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)

2024-05-28 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/93559

>From 5c8258fb2bcc102d431af9f3ae41cf72ecc335b6 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 28 May 2024 15:43:45 +0100
Subject: [PATCH] [clang][ExtractAPI] Flatten all enum cases from anonymous
 enums at top level

rdar://128863241
---
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  65 +-
 .../ExtractAPI/anonymous_record_no_typedef.c  |  42 ++-
 clang/test/ExtractAPI/enum.c  | 112 --
 clang/tools/libclang/CXExtractAPI.cpp |   3 +
 4 files changed, 54 insertions(+), 168 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 8ccebe457ed53..76d7fd798bed3 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -21,6 +21,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ParentMapContext.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
@@ -127,7 +128,7 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 protected:
   /// Collect API information for the enum constants and associate with the
   /// parent enum.
-  void recordEnumConstants(EnumRecord *EnumRecord,
+  void recordEnumConstants(SymbolReference Container,
const EnumDecl::enumerator_range Constants);
 
   /// Collect API information for the Objective-C methods and associate with 
the
@@ -248,12 +249,8 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 clang::index::generateUSRForDecl(Tag, TagUSR);
 if (auto *Record = llvm::dyn_cast_if_present(
 API.findRecordForUSR(TagUSR))) {
-  if (Record->IsEmbeddedInVarDeclarator) {
+  if (Record->IsEmbeddedInVarDeclarator)
 NewRecordContext->stealRecordChain(*Record);
-auto *NewRecord = cast(NewRecordContext);
-if (NewRecord->Comment.empty())
-  NewRecord->Comment = Record->Comment;
-  }
 }
   }
 };
@@ -394,17 +391,6 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const 
EnumDecl *Decl) {
   if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
 return true;
 
-  SmallString<128> QualifiedNameBuffer;
-  // Collect symbol information.
-  StringRef Name = Decl->getName();
-  if (Name.empty())
-Name = getTypedefName(Decl);
-  if (Name.empty()) {
-llvm::raw_svector_ostream OS(QualifiedNameBuffer);
-Decl->printQualifiedName(OS);
-Name = QualifiedNameBuffer;
-  }
-
   SmallString<128> USR;
   index::generateUSRForDecl(Decl, USR);
   PresumedLoc Loc =
@@ -420,13 +406,29 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const 
EnumDecl *Decl) {
   DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
   DeclarationFragments SubHeading =
   DeclarationFragmentsBuilder::getSubHeading(Decl);
-  auto *ER = API.createRecord(
-  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
-  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
-  isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
+
+  // Collect symbol information.
+  SymbolReference ParentContainer;
+
+  if (Decl->hasNameForLinkage()) {
+StringRef Name = Decl->getName();
+if (Name.empty())
+  Name = getTypedefName(Decl);
+
+auto *ER = API.createRecord(
+USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
+AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
+SubHeading, isInSystemHeader(Decl), false);
+ParentContainer = SymbolReference(ER);
+  } else {
+// If this an anonymous enum then the parent scope of the constants is the
+// top level namespace.
+ParentContainer = {};
+  }
 
   // Now collect information about the enumerators in this enum.
-  getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
+  getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
+Decl->enumerators());
 
   return true;
 }
@@ -1197,7 +1199,7 @@ bool 
ExtractAPIVisitorBase::VisitObjCCategoryDecl(
 /// parent enum.
 template 
 void ExtractAPIVisitorBase::recordEnumConstants(
-EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
+SymbolReference Container, const EnumDecl::enumerator_range Constants) {
   for (const auto *Constant : Constants) {
 // Collect symbol information.
 StringRef Name = Constant->getName();
@@ -1218,9 +1220,8 @@ void ExtractAPIVisitorBase::recordEnumConstants(
 DeclarationFragmentsBuilder::getSubHeading(Constant);
 
 API.createRecord(
-USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
-AvailabilityInfo::createFromDecl(Constant), Comment, Declaration,
-SubHeading, isInSystemHeader(Constan

[clang] [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (PR #93559)

2024-05-28 Thread Daniel Grumberg via cfe-commits

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

rdar://128863241

>From d453e5b21d369d8c2b1d06c640887ec81ace Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 28 May 2024 15:43:45 +0100
Subject: [PATCH] [clang][ExtractAPI] Flatten all enum cases from anonymous
 enums at top level

rdar://128863241
---
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  57 +
 .../ExtractAPI/anonymous_record_no_typedef.c  |  42 ++-
 clang/test/ExtractAPI/enum.c  | 112 --
 clang/tools/libclang/CXExtractAPI.cpp |   3 +
 4 files changed, 50 insertions(+), 164 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 8ccebe457ed53..9df5138a223da 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -21,6 +21,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ParentMapContext.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
@@ -127,7 +128,7 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 protected:
   /// Collect API information for the enum constants and associate with the
   /// parent enum.
-  void recordEnumConstants(EnumRecord *EnumRecord,
+  void recordEnumConstants(SymbolReference Container,
const EnumDecl::enumerator_range Constants);
 
   /// Collect API information for the Objective-C methods and associate with 
the
@@ -248,12 +249,8 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 clang::index::generateUSRForDecl(Tag, TagUSR);
 if (auto *Record = llvm::dyn_cast_if_present(
 API.findRecordForUSR(TagUSR))) {
-  if (Record->IsEmbeddedInVarDeclarator) {
+  if (Record->IsEmbeddedInVarDeclarator)
 NewRecordContext->stealRecordChain(*Record);
-auto *NewRecord = cast(NewRecordContext);
-if (NewRecord->Comment.empty())
-  NewRecord->Comment = Record->Comment;
-  }
 }
   }
 };
@@ -394,17 +391,6 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const 
EnumDecl *Decl) {
   if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
 return true;
 
-  SmallString<128> QualifiedNameBuffer;
-  // Collect symbol information.
-  StringRef Name = Decl->getName();
-  if (Name.empty())
-Name = getTypedefName(Decl);
-  if (Name.empty()) {
-llvm::raw_svector_ostream OS(QualifiedNameBuffer);
-Decl->printQualifiedName(OS);
-Name = QualifiedNameBuffer;
-  }
-
   SmallString<128> USR;
   index::generateUSRForDecl(Decl, USR);
   PresumedLoc Loc =
@@ -420,13 +406,27 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const 
EnumDecl *Decl) {
   DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
   DeclarationFragments SubHeading =
   DeclarationFragmentsBuilder::getSubHeading(Decl);
-  auto *ER = API.createRecord(
+
+  // Collect symbol information.
+  SymbolReference ParentContainer;
+
+  if (Decl->hasNameForLinkage()) {
+StringRef Name = Decl->getName();
+if (Name.empty())
+  Name = getTypedefName(Decl);
+
+auto *ER = API.createRecord(
   USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
   AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
-  isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
+  isInSystemHeader(Decl), false);
+ParentContainer = SymbolReference(ER);
+  } else {
+// If this an anonymous enum then the parent scope of the constants is the 
top level namespace.
+ParentContainer = {};
+  }
 
   // Now collect information about the enumerators in this enum.
-  getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
+  getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer, 
Decl->enumerators());
 
   return true;
 }
@@ -1197,7 +1197,7 @@ bool 
ExtractAPIVisitorBase::VisitObjCCategoryDecl(
 /// parent enum.
 template 
 void ExtractAPIVisitorBase::recordEnumConstants(
-EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
+SymbolReference Container, const EnumDecl::enumerator_range Constants) {
   for (const auto *Constant : Constants) {
 // Collect symbol information.
 StringRef Name = Constant->getName();
@@ -1218,7 +1218,7 @@ void ExtractAPIVisitorBase::recordEnumConstants(
 DeclarationFragmentsBuilder::getSubHeading(Constant);
 
 API.createRecord(
-USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
+USR, Name, Container, Loc,
 AvailabilityInfo::createFromDecl(Constant), Comment, Declaration,
 SubHeading, isInSystemHeader(Constant));
   }
@@ -1469,7 +1469,18 @@ class ExtractAPIVisitor
 
   bool shouldDeclBeIncluded(const Decl *D) const { return true; }
   const RawComment *fetchRawCom

[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)

2024-05-24 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)

2024-05-23 Thread Daniel Grumberg via cfe-commits

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

None

>From d4e7e838fcbdf1645e5e31cefb462d53e59361d4 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 23 May 2024 15:24:53 +0100
Subject: [PATCH] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only
 accessed if available

---
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 32 +-
 clang/test/ExtractAPI/non_type_template.cpp   | 44 +++
 2 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 904b9315f26ef..8c7c0f8a14726 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1084,12 +1084,22 @@ 
DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
 
   if (StringRef(ArgumentFragment.begin()->Spelling)
   .starts_with("type-parameter")) {
-std::string ProperArgName = TemplateArgumentLocs.value()[i]
-.getTypeSourceInfo()
-->getType()
-.getAsString();
-ArgumentFragment.begin()->Spelling.swap(ProperArgName);
+if (TemplateArgumentLocs.has_value() &&
+TemplateArgumentLocs->size() > i) {
+  std::string ProperArgName = TemplateArgumentLocs.value()[i]
+  .getTypeSourceInfo()
+  ->getType()
+  .getAsString();
+  ArgumentFragment.begin()->Spelling.swap(ProperArgName);
+} else {
+  auto &Spelling = ArgumentFragment.begin()->Spelling;
+  Spelling.clear();
+  raw_string_ostream OutStream(Spelling);
+  CTA.print(Context.getPrintingPolicy(), OutStream, false);
+  OutStream.flush();
+}
   }
+
   Fragments.append(std::move(ArgumentFragment));
   break;
 }
@@ -1212,9 +1222,9 @@ 
DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization(
   cast(Decl)))
   .pop_back() // there is an extra semicolon now
   .append("<", DeclarationFragments::FragmentKind::Text)
-  .append(
-  getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
-   Decl->getASTContext(), 
std::nullopt))
+  .append(getFragmentsForTemplateArguments(
+  Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
+  Decl->getTemplateArgsAsWritten()->arguments()))
   .append(">", DeclarationFragments::FragmentKind::Text)
   .appendSemicolon();
 }
@@ -1255,9 +1265,9 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization(
   .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl))
   .pop_back() // there is an extra semicolon now
   .append("<", DeclarationFragments::FragmentKind::Text)
-  .append(
-  getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
-   Decl->getASTContext(), 
std::nullopt))
+  .append(getFragmentsForTemplateArguments(
+  Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
+  Decl->getTemplateArgsAsWritten()->arguments()))
   .append(">", DeclarationFragments::FragmentKind::Text)
   .appendSemicolon();
 }
diff --git a/clang/test/ExtractAPI/non_type_template.cpp 
b/clang/test/ExtractAPI/non_type_template.cpp
index 4e65eb790ca11..85f38e39c82bc 100644
--- a/clang/test/ExtractAPI/non_type_template.cpp
+++ b/clang/test/ExtractAPI/non_type_template.cpp
@@ -310,4 +310,48 @@ NestedTemplateTemplateParamPack var;
 // VAR-NEXT:   }
 // VAR-NEXT: ]
 
+template 
+class TypeContainer {
+  public:
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix 
TYPE
+typedef Foo Type;
+// TYPE-LABEL: "!testLabel": 
"c:non_type_template.cpp@ST>1#T@TypeContainer@T@Type",
+// TYPE:  "declarationFragments": [
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "keyword",
+// TYPE-NEXT: "spelling": "typedef"
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": " "
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "typeIdentifier",
+// TYPE-NEXT: "preciseIdentifier": "c:@ST>2#T#NI@Foo",
+// TYPE-NEXT: "spelling": "Foo"
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": "<"
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "typeIdentifier",
+// TYPE-NEXT: "preciseIdentifier": "c:t0.0",
+// TYPE-NEXT: "spelling": "T"
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": "> "
+// TYPE-NEXT:   },
+// TYPE-NEXT:   {
+// TYPE-NEXT: "kind": "identifier",
+// TYPE-NEXT: "spelling": "Type"
+// TYPE-

[clang] [clang][ExtractAPI] Remove symbols defined in categories to external types unless requested (PR #92522)

2024-05-20 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Remove symbols defined in categories to external types unless requested (PR #92522)

2024-05-17 Thread Daniel Grumberg via cfe-commits

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

rdar://128259890

>From 7650c18c883bb14e5a4b17d6b6d61297f2fa3c44 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 17 May 2024 11:58:18 +0100
Subject: [PATCH] [clang][ExtractAPI] Remove symbols defined in categories to
 external types unless requested

rdar://128259890
---
 .../Serialization/SymbolGraphSerializer.h  |  9 +++--
 .../Serialization/SymbolGraphSerializer.cpp| 11 +--
 clang/test/ExtractAPI/objc_external_category.m | 18 +-
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git 
a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h 
b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
index 724b087f7aea9..27e9167ca1ad0 100644
--- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
+++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
@@ -102,6 +102,8 @@ class SymbolGraphSerializer : public 
APISetVisitor {
 
   const bool EmitSymbolLabelsForTesting = false;
 
+  const bool SkipSymbolsInCategoriesToExternalTypes = false;
+
   /// The object instantiated by the last call to serializeAPIRecord.
   Object *CurrentSymbol = nullptr;
 
@@ -271,10 +273,13 @@ class SymbolGraphSerializer : public 
APISetVisitor {
 
   SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList,
 bool EmitSymbolLabelsForTesting = false,
-bool ForceEmitToMainModule = false)
+bool ForceEmitToMainModule = false,
+bool SkipSymbolsInCategoriesToExternalTypes = false)
   : Base(API), ForceEmitToMainModule(ForceEmitToMainModule),
 IgnoresList(IgnoresList),
-EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting) {}
+EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting),
+SkipSymbolsInCategoriesToExternalTypes(
+SkipSymbolsInCategoriesToExternalTypes) {}
 };
 
 } // namespace extractapi
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index c16d4623f115d..08e711cafae28 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -925,6 +925,10 @@ bool SymbolGraphSerializer::visitObjCInterfaceRecord(
 
 bool SymbolGraphSerializer::traverseObjCCategoryRecord(
 const ObjCCategoryRecord *Record) {
+  if (SkipSymbolsInCategoriesToExternalTypes &&
+  !API.findRecordForUSR(Record->Interface.USR))
+return true;
+
   auto *CurrentModule = ModuleForCurrentSymbol;
   if (Record->isExtendingExternalModule())
 ModuleForCurrentSymbol = &ExtendedModules[Record->Interface.Source];
@@ -1040,8 +1044,11 @@ void SymbolGraphSerializer::serializeGraphToStream(
 void SymbolGraphSerializer::serializeMainSymbolGraph(
 raw_ostream &OS, const APISet &API, const APIIgnoresList &IgnoresList,
 SymbolGraphSerializerOption Options) {
-  SymbolGraphSerializer Serializer(API, IgnoresList,
-   Options.EmitSymbolLabelsForTesting);
+  SymbolGraphSerializer Serializer(
+  API, IgnoresList, Options.EmitSymbolLabelsForTesting,
+  /*ForceEmitToMainModule=*/true,
+  /*SkipSymbolsInCategoriesToExternalTypes=*/true);
+
   Serializer.traverseAPISet();
   Serializer.serializeGraphToStream(OS, Options, API.ProductName,
 std::move(Serializer.MainModule));
diff --git a/clang/test/ExtractAPI/objc_external_category.m 
b/clang/test/ExtractAPI/objc_external_category.m
index 47e699cb91c0e..8afc92489f28b 100644
--- a/clang/test/ExtractAPI/objc_external_category.m
+++ b/clang/test/ExtractAPI/objc_external_category.m
@@ -4,6 +4,9 @@
 // RUN:   --emit-extension-symbol-graphs --symbol-graph-dir=%t/symbols \
 // RUN:   --product-name=Module -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules-cache \
 // RUN:   -triple arm64-apple-macosx -x objective-c-header %t/input.h -verify
+// RUN: %clang_cc1 -extract-api --pretty-sgf 
--emit-sgf-symbol-labels-for-testing \
+// RUN:   --product-name=Module -o %t/ModuleNoExt.symbols.json -triple 
arm64-apple-macosx \
+// RUN:   -x objective-c-header %t/input.h
 
 //--- input.h
 #include "ExternalModule.h"
@@ -28,15 +31,20 @@ @interface ExtInterface
 header "ExternalModule.h"
 }
 
+// Main symbol graph from the build with extension SGFs
 // RUN: FileCheck %s --input-file  %t/symbols/Module.symbols.json 
--check-prefix MOD
+
 // MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(py)Property $ 
c:objc(cs)ExtInterface"
 // MOD-NOT: "!testRelLabel": "memberOf $ 
c:objc(cs)ExtInterface(im)InstanceMethod $ c:objc(cs)ExtInterface"
 // MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(cm)ClassMethod 
$ c:objc(cs)ExtInterface"
-// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface(py)P

[clang] [clang][ExtractAPI] Correctly generate declaration fragments for non-type template parameters (PR #91958)

2024-05-17 Thread Daniel Grumberg via cfe-commits

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


[clang] [ExtractAPI,test] fix filecheck annotation (PR #92231)

2024-05-15 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.

LGTM! Thanks for doing this!

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


[clang] [clang][ExtractAPI] Correctly generate declaration fragments for non-type template parameters (PR #91958)

2024-05-13 Thread Daniel Grumberg via cfe-commits

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

Previously we only generated declaration fragments for template type 
parameters/arguments, this adds supports for most other possible template 
parameters/arguments.

rdar://127732598

>From d86e4256da57451a08d580b8eecd5525bd1642c6 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 8 May 2024 12:22:47 +0100
Subject: [PATCH] [clang][ExtractAPI] Correctly generate declaration fragments
 for non-type template parameters.

Previously we only generated declaration fragments for template type
paramters/arguments, this adds supports for most other possible template
parameters/arguments.

rdar://127732598
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 226 ++---
 clang/test/ExtractAPI/class_template.cpp  |   2 +-
 .../class_template_param_inheritance.cpp  |   2 +-
 .../class_template_partial_spec.cpp   |   4 +-
 clang/test/ExtractAPI/class_template_spec.cpp |   4 +-
 clang/test/ExtractAPI/concept.cpp |   2 +-
 clang/test/ExtractAPI/field_template.cpp  |   2 +-
 .../test/ExtractAPI/global_func_template.cpp  |   4 +-
 .../ExtractAPI/global_func_template_spec.cpp  |   4 +-
 clang/test/ExtractAPI/global_var_template.cpp |   2 +-
 .../global_var_template_partial_spec.cpp  |   4 +-
 .../ExtractAPI/global_var_template_spec.cpp   |   4 +-
 clang/test/ExtractAPI/method_template.cpp |   2 +-
 .../test/ExtractAPI/method_template_spec.cpp  |   4 +-
 clang/test/ExtractAPI/non_type_template.cpp   | 313 ++
 15 files changed, 522 insertions(+), 57 deletions(-)
 create mode 100644 clang/test/ExtractAPI/non_type_template.cpp

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 9bf7950888dbb..98b9343924a83 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -12,13 +12,19 @@
 
//===--===//
 
 #include "clang/ExtractAPI/DeclarationFragments.h"
+#include "clang/AST/ASTFwd.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
 
 using namespace clang::extractapi;
 using namespace llvm;
@@ -386,6 +392,25 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 getFragmentsForType(AT->getElementType(), Context, After));
   }
 
+  if (const TemplateSpecializationType *TemplSpecTy =
+  dyn_cast(T)) {
+const auto TemplName = TemplSpecTy->getTemplateName();
+std::string Str;
+raw_string_ostream Stream(Str);
+TemplName.print(Stream, Context.getPrintingPolicy(),
+TemplateName::Qualified::AsWritten);
+SmallString<64> USR("");
+if (const auto *TemplDecl = TemplName.getAsTemplateDecl())
+  index::generateUSRForDecl(TemplDecl, USR);
+
+return Fragments
+.append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, USR)
+.append("<", DeclarationFragments::FragmentKind::Text)
+.append(getFragmentsForTemplateArguments(
+TemplSpecTy->template_arguments(), Context, std::nullopt))
+.append(">", DeclarationFragments::FragmentKind::Text);
+  }
+
   // Everything we care about has been handled now, reduce to the canonical
   // unqualified base type.
   QualType Base = T->getCanonicalTypeUnqualified();
@@ -650,7 +675,6 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForBlock(
 DeclarationFragments
 DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) 
{
   DeclarationFragments Fragments;
-  // FIXME: Handle template specialization
   switch (Func->getStorageClass()) {
   case SC_None:
   case SC_PrivateExtern:
@@ -952,27 +976,84 @@ 
DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
   Fragments.append(",", DeclarationFragments::FragmentKind::Text)
   .appendSpace();
 
-const auto *TemplateParam =
-dyn_cast(ParameterArray[i]);
-if (!TemplateParam)
-  continue;
-if (TemplateParam->hasTypeConstraint())
-  Fragments.append(TemplateParam->getTypeConstraint()
-   ->getNamedConcept()
-   ->getName()
-   .str(),
-   DeclarationFragments::FragmentKind::TypeIdentifier);
-else if (TemplateParam->wasDeclaredWithTypename())
-  Fragments.append("typename", 
DeclarationFragments::FragmentKind::Keyword);
-else
-  Fragments.append("class", DeclarationFragments::FragmentKind::Keyword);
-
-if (TemplateParam->isParam

[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)

2024-05-13 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang-tools-extra] [flang] [llvm] [mlir] [polly] [test]: fix filecheck annotation typos (PR #91854)

2024-05-13 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.

LGTM to me for the ExtractAPI one.

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


[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)

2024-05-09 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/91466

>From a8c7763ed5f36e4faeba5eece2827b2dec010734 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 8 May 2024 11:55:15 +0100
Subject: [PATCH] [clang][ExtractAPI] Distinguish between record kind for
 display and for RTTI

rdar://127732562
---
 clang/include/clang/ExtractAPI/API.h  |  7 --
 .../clang/ExtractAPI/ExtractAPIVisitor.h  | 25 +++
 .../Serialization/SymbolGraphSerializer.cpp   |  6 ++---
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index d323e1668a72..bf291074fd06 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -266,6 +266,8 @@ struct APIRecord {
 
   AccessControl Access;
 
+  RecordKind KindForDisplay;
+
 private:
   const RecordKind Kind;
   friend class RecordContext;
@@ -277,6 +279,7 @@ struct APIRecord {
   APIRecord *getNextInContext() const { return NextInContext; }
 
   RecordKind getKind() const { return Kind; }
+  RecordKind getKindForDisplay() const { return KindForDisplay; }
 
   static APIRecord *castFromRecordContext(const RecordContext *Ctx);
   static RecordContext *castToRecordContext(const APIRecord *Record);
@@ -293,10 +296,10 @@ struct APIRecord {
 Availability(std::move(Availability)), Linkage(Linkage),
 Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
 IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
-Kind(Kind) {}
+KindForDisplay(Kind), Kind(Kind) {}
 
   APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
-  : USR(USR), Name(Name), Kind(Kind) {}
+  : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {}
 
   // Pure virtual destructor to make APIRecord abstract
   virtual ~APIRecord() = 0;
diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 97cc457ea2a9..8ccebe457ed5 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -194,6 +194,15 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 return Bases;
   }
 
+  APIRecord::RecordKind getKindForDisplay(const CXXRecordDecl *Decl) {
+if (Decl->isUnion())
+  return APIRecord::RK_Union;
+if (Decl->isStruct())
+  return APIRecord::RK_Struct;
+
+return APIRecord::RK_CXXClass;
+  }
+
   StringRef getOwningModuleName(const Decl &D) {
 if (auto *OwningModule = D.getImportedOwningModule())
   return OwningModule->Name;
@@ -599,13 +608,6 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl(
   DeclarationFragments SubHeading =
   DeclarationFragmentsBuilder::getSubHeading(Decl);
 
-  APIRecord::RecordKind Kind;
-  if (Decl->isUnion())
-Kind = APIRecord::RecordKind::RK_Union;
-  else if (Decl->isStruct())
-Kind = APIRecord::RecordKind::RK_Struct;
-  else
-Kind = APIRecord::RecordKind::RK_CXXClass;
   auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
 
   CXXClassRecord *Record;
@@ -619,13 +621,15 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl(
 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
 isInSystemHeader(Decl));
-  } else
+  } else {
 Record = API.createRecord(
 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
-SubHeading, Kind, Access, isInSystemHeader(Decl),
-isEmbeddedInVarDeclarator(*Decl));
+SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
+isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
+  }
 
+  Record->KindForDisplay = getKindForDisplay(Decl);
   Record->Bases = getBases(Decl);
 
   return true;
@@ -849,6 +853,7 @@ bool ExtractAPIVisitorBase::
   Template(Decl), DeclarationFragmentsBuilder::getAccessControl(Decl),
   isInSystemHeader(Decl));
 
+  CTPSR->KindForDisplay = getKindForDisplay(Decl);
   CTPSR->Bases = getBases(Decl);
 
   return true;
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 34278b5d40c4..c16d4623f115 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -514,7 +514,7 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, 
Language Lang) {
 /// which is prefixed by the source language name, useful for tooling to parse
 /// the kind, and a \c displayName for rendering human-readable names.
 Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
-  return serializeSymbolKind(Record.getKind(), Lang);
+  return serializeSymbolKind(Record.KindForDisplay, Lang);
 }
 
 /// Serialize the f

[clang] [clang][ExtractAPI] Distinguish between record kind for display and for RTTI (PR #91466)

2024-05-08 Thread Daniel Grumberg via cfe-commits

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

rdar://127732562

>From d1118a8552d84e044cd0f22cd8b46e5e65b43cae Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 8 May 2024 11:55:15 +0100
Subject: [PATCH] [clang][ExtractAPI] Distinguish between record kind for
 display and for RTTI

---
 clang/include/clang/ExtractAPI/API.h  |  6 +++--
 .../clang/ExtractAPI/ExtractAPIVisitor.h  | 23 +++
 .../Serialization/SymbolGraphSerializer.cpp   |  4 ++--
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index d323e1668a72b..d2341f004c52f 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -266,6 +266,7 @@ struct APIRecord {
 
   AccessControl Access;
 
+  RecordKind KindForDisplay;
 private:
   const RecordKind Kind;
   friend class RecordContext;
@@ -277,6 +278,7 @@ struct APIRecord {
   APIRecord *getNextInContext() const { return NextInContext; }
 
   RecordKind getKind() const { return Kind; }
+  RecordKind getKindForDisplay() const { return KindForDisplay; }
 
   static APIRecord *castFromRecordContext(const RecordContext *Ctx);
   static RecordContext *castToRecordContext(const APIRecord *Record);
@@ -293,10 +295,10 @@ struct APIRecord {
 Availability(std::move(Availability)), Linkage(Linkage),
 Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
 IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
-Kind(Kind) {}
+KindForDisplay(Kind), Kind(Kind) {}
 
   APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
-  : USR(USR), Name(Name), Kind(Kind) {}
+  : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {}
 
   // Pure virtual destructor to make APIRecord abstract
   virtual ~APIRecord() = 0;
diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 97cc457ea2a92..482a81f750a76 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -194,6 +194,15 @@ class ExtractAPIVisitorBase : public 
RecursiveASTVisitor {
 return Bases;
   }
 
+  APIRecord::RecordKind getKindForDisplay(const CXXRecordDecl *Decl) {
+if (Decl->isUnion())
+  return APIRecord::RK_Union;
+if (Decl->isStruct())
+  return APIRecord::RK_Struct;
+
+return APIRecord::RK_CXXClass;
+  }
+
   StringRef getOwningModuleName(const Decl &D) {
 if (auto *OwningModule = D.getImportedOwningModule())
   return OwningModule->Name;
@@ -599,13 +608,6 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl(
   DeclarationFragments SubHeading =
   DeclarationFragmentsBuilder::getSubHeading(Decl);
 
-  APIRecord::RecordKind Kind;
-  if (Decl->isUnion())
-Kind = APIRecord::RecordKind::RK_Union;
-  else if (Decl->isStruct())
-Kind = APIRecord::RecordKind::RK_Struct;
-  else
-Kind = APIRecord::RecordKind::RK_CXXClass;
   auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
 
   CXXClassRecord *Record;
@@ -619,13 +621,15 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl(
 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
 isInSystemHeader(Decl));
-  } else
+  } else {
 Record = API.createRecord(
 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
-SubHeading, Kind, Access, isInSystemHeader(Decl),
+SubHeading, APIRecord::RecordKind::RK_CXXClass, Access, 
isInSystemHeader(Decl),
 isEmbeddedInVarDeclarator(*Decl));
+  }
 
+  Record->KindForDisplay = getKindForDisplay(Decl);
   Record->Bases = getBases(Decl);
 
   return true;
@@ -849,6 +853,7 @@ bool ExtractAPIVisitorBase::
   Template(Decl), DeclarationFragmentsBuilder::getAccessControl(Decl),
   isInSystemHeader(Decl));
 
+  CTPSR->KindForDisplay = getKindForDisplay(Decl);
   CTPSR->Bases = getBases(Decl);
 
   return true;
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 34278b5d40c42..952deccded07d 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -514,7 +514,7 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, 
Language Lang) {
 /// which is prefixed by the source language name, useful for tooling to parse
 /// the kind, and a \c displayName for rendering human-readable names.
 Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
-  return serializeSymbolKind(Record.getKind(), Lang);
+  return serializeSymbolKind(Record.KindForDisplay, Lang);
 }
 
 /// Serialize the function signature field, as specified by

[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-24 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-23 Thread Daniel Grumberg via cfe-commits


@@ -54,6 +54,20 @@ RecordContext *APIRecord::castToRecordContext(const 
APIRecord *Record) {
   }
 }
 
+void RecordContext::stealRecordChain(RecordContext &Other) {
+  // If we don't have an empty chain append Other's chain into ours.
+  if (First)
+Last->NextInContext = Other.First;

daniel-grumberg wrote:

Documented the invariant that `First` being non-null implies that `Last` is 
also non-null in an assert above.

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


[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-23 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/87772

>From 18912352db31406c7c5b530d6e22f77e775fbf38 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 4 Apr 2024 18:33:25 +0100
Subject: [PATCH 1/3] [clang][ExtractAPI] Fix handling of anonymous TagDecls

This changes the handling of anonymous TagDecls to the following rules:
- If the TagDecl is embedded in the declaration for some VarDecl (this
  is the only possibility for RecordDecls), then pretend the child decls
  belong to the VarDecl
- If it's an EnumDecl proceed as we did previously, i.e., embed it in
  the enclosing DeclContext.

Additionally this fixes a few issues with declaration fragments not
consistently including "{ ... }" for anonymous TagDecls. To make testing
these additions easier this patch fixes some text declaration fragments
merging issues and updates tests accordingly.
---
 clang/include/clang/ExtractAPI/API.h  | 132 ++--
 clang/include/clang/ExtractAPI/APIRecords.inc |  16 +-
 .../clang/ExtractAPI/DeclarationFragments.h   |  84 ++-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  76 ++-
 clang/lib/ExtractAPI/API.cpp  |   8 +
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  17 +-
 .../Serialization/SymbolGraphSerializer.cpp   |   8 +
 .../ExtractAPI/anonymous_record_no_typedef.c  | 565 +-
 clang/test/ExtractAPI/enum.c  |  12 +-
 clang/test/ExtractAPI/function_noexcepts.cpp  |  18 +-
 clang/test/ExtractAPI/methods.cpp |   6 +-
 clang/test/ExtractAPI/objc_block.m|  48 +-
 .../ExtractAPI/typedef_anonymous_record.c |   4 +-
 clang/test/ExtractAPI/typedef_struct_enum.c   |   2 +-
 14 files changed, 427 insertions(+), 569 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 92cacf65c7d64e..05cfabd072a560 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -208,20 +208,20 @@ struct APIRecord {
 RK_ClassTemplate,
 RK_ClassTemplateSpecialization,
 RK_ClassTemplatePartialSpecialization,
-RK_LastRecordContext,
-RK_GlobalFunction,
-RK_GlobalFunctionTemplate,
-RK_GlobalFunctionTemplateSpecialization,
+RK_StructField,
+RK_UnionField,
+RK_CXXField,
+RK_StaticField,
+RK_CXXFieldTemplate,
 RK_GlobalVariable,
 RK_GlobalVariableTemplate,
 RK_GlobalVariableTemplateSpecialization,
 RK_GlobalVariableTemplatePartialSpecialization,
+RK_LastRecordContext,
+RK_GlobalFunction,
+RK_GlobalFunctionTemplate,
+RK_GlobalFunctionTemplateSpecialization,
 RK_EnumConstant,
-RK_StructField,
-RK_UnionField,
-RK_StaticField,
-RK_CXXField,
-RK_CXXFieldTemplate,
 RK_Concept,
 RK_CXXStaticMethod,
 RK_CXXInstanceMethod,
@@ -321,6 +321,8 @@ class RecordContext {
 
   RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
 
+  void stealRecordChain(RecordContext &Other);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : 
GlobalFunctionRecord {
 };
 
 /// This holds information associated with global functions.
-struct GlobalVariableRecord : APIRecord {
+struct GlobalVariableRecord : APIRecord, RecordContext {
   GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
LinkageInfo Linkage, const DocComment &Comment,
@@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord {
DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
   : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
   std::move(Availability), Linkage, Comment, Declaration,
-  SubHeading, IsFromSystemHeader) {}
+  SubHeading, IsFromSystemHeader),
+RecordContext(RK_GlobalVariable) {}
 
   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
-   SymbolReference Parent,
-
-   PresumedLoc Loc, AvailabilityInfo Availability,
-   LinkageInfo Linkage, const DocComment &Comment,
+   SymbolReference Parent, PresumedLoc Loc,
+   AvailabilityInfo Availability, LinkageInfo Linkage,
+   const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
   : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
   Linkage, Comment, Declaration, SubHeading,
-  IsFromSystemHeader) {}
+  IsFromSystemHeader),
+RecordContext(Kind) {}
 
   static bool classof(const APIRecord *Record) {
 return classofKind(Record->getKind());
   }
-  static bool classofKind(RecordK

[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-23 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/87772

>From 18912352db31406c7c5b530d6e22f77e775fbf38 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 4 Apr 2024 18:33:25 +0100
Subject: [PATCH 1/2] [clang][ExtractAPI] Fix handling of anonymous TagDecls

This changes the handling of anonymous TagDecls to the following rules:
- If the TagDecl is embedded in the declaration for some VarDecl (this
  is the only possibility for RecordDecls), then pretend the child decls
  belong to the VarDecl
- If it's an EnumDecl proceed as we did previously, i.e., embed it in
  the enclosing DeclContext.

Additionally this fixes a few issues with declaration fragments not
consistently including "{ ... }" for anonymous TagDecls. To make testing
these additions easier this patch fixes some text declaration fragments
merging issues and updates tests accordingly.
---
 clang/include/clang/ExtractAPI/API.h  | 132 ++--
 clang/include/clang/ExtractAPI/APIRecords.inc |  16 +-
 .../clang/ExtractAPI/DeclarationFragments.h   |  84 ++-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  76 ++-
 clang/lib/ExtractAPI/API.cpp  |   8 +
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  17 +-
 .../Serialization/SymbolGraphSerializer.cpp   |   8 +
 .../ExtractAPI/anonymous_record_no_typedef.c  | 565 +-
 clang/test/ExtractAPI/enum.c  |  12 +-
 clang/test/ExtractAPI/function_noexcepts.cpp  |  18 +-
 clang/test/ExtractAPI/methods.cpp |   6 +-
 clang/test/ExtractAPI/objc_block.m|  48 +-
 .../ExtractAPI/typedef_anonymous_record.c |   4 +-
 clang/test/ExtractAPI/typedef_struct_enum.c   |   2 +-
 14 files changed, 427 insertions(+), 569 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 92cacf65c7d64e..05cfabd072a560 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -208,20 +208,20 @@ struct APIRecord {
 RK_ClassTemplate,
 RK_ClassTemplateSpecialization,
 RK_ClassTemplatePartialSpecialization,
-RK_LastRecordContext,
-RK_GlobalFunction,
-RK_GlobalFunctionTemplate,
-RK_GlobalFunctionTemplateSpecialization,
+RK_StructField,
+RK_UnionField,
+RK_CXXField,
+RK_StaticField,
+RK_CXXFieldTemplate,
 RK_GlobalVariable,
 RK_GlobalVariableTemplate,
 RK_GlobalVariableTemplateSpecialization,
 RK_GlobalVariableTemplatePartialSpecialization,
+RK_LastRecordContext,
+RK_GlobalFunction,
+RK_GlobalFunctionTemplate,
+RK_GlobalFunctionTemplateSpecialization,
 RK_EnumConstant,
-RK_StructField,
-RK_UnionField,
-RK_StaticField,
-RK_CXXField,
-RK_CXXFieldTemplate,
 RK_Concept,
 RK_CXXStaticMethod,
 RK_CXXInstanceMethod,
@@ -321,6 +321,8 @@ class RecordContext {
 
   RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
 
+  void stealRecordChain(RecordContext &Other);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : 
GlobalFunctionRecord {
 };
 
 /// This holds information associated with global functions.
-struct GlobalVariableRecord : APIRecord {
+struct GlobalVariableRecord : APIRecord, RecordContext {
   GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
LinkageInfo Linkage, const DocComment &Comment,
@@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord {
DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
   : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
   std::move(Availability), Linkage, Comment, Declaration,
-  SubHeading, IsFromSystemHeader) {}
+  SubHeading, IsFromSystemHeader),
+RecordContext(RK_GlobalVariable) {}
 
   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
-   SymbolReference Parent,
-
-   PresumedLoc Loc, AvailabilityInfo Availability,
-   LinkageInfo Linkage, const DocComment &Comment,
+   SymbolReference Parent, PresumedLoc Loc,
+   AvailabilityInfo Availability, LinkageInfo Linkage,
+   const DocComment &Comment,
DeclarationFragments Declaration,
DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
   : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
   Linkage, Comment, Declaration, SubHeading,
-  IsFromSystemHeader) {}
+  IsFromSystemHeader),
+RecordContext(Kind) {}
 
   static bool classof(const APIRecord *Record) {
 return classofKind(Record->getKind());
   }
-  static bool classofKind(RecordK

[clang] [clang][ExtractAPI] Serialize platform specific unavailable attribute in symbol graphs (PR #89277)

2024-04-23 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-16 Thread Daniel Grumberg via cfe-commits


@@ -54,6 +54,13 @@ RecordContext *APIRecord::castToRecordContext(const 
APIRecord *Record) {
   }
 }
 
+void RecordContext::stealRecordChain(RecordContext &Other) {
+  First = Other.First;
+  Last = Other.Last;
+  Other.First = nullptr;
+  Other.Last = nullptr;
+}

daniel-grumberg wrote:

There is no harm in "stealing" an empty record chain, and it's not necessarily 
even semantically wrong, all it indicates is that the current RecordContext 
won't have any children during any traversals. Semantic problems would still be 
caught by having a test.

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


[clang] Update ExtractAPIConsumer.cpp (PR #88285)

2024-04-10 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.

LGTM!

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


[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-10 Thread Daniel Grumberg via cfe-commits


@@ -54,6 +54,13 @@ RecordContext *APIRecord::castToRecordContext(const 
APIRecord *Record) {
   }
 }
 
+void RecordContext::stealRecordChain(RecordContext &Other) {
+  First = Other.First;
+  Last = Other.Last;
+  Other.First = nullptr;
+  Other.Last = nullptr;
+}

daniel-grumberg wrote:

Maybe a better name for this would be `transferRecordChain`?

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


[clang] [clang][ExtractAPI] Fix handling of anonymous TagDecls (PR #87772)

2024-04-05 Thread Daniel Grumberg via cfe-commits

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

This changes the handling of anonymous TagDecls to the following rules:
- If the TagDecl is embedded in the declaration for some VarDecl (this is the 
only possibility for RecordDecls), then pretend the child decls belong to the 
VarDecl
- If it's an EnumDecl proceed as we did previously, i.e., embed it in the 
enclosing DeclContext.

Additionally this fixes a few issues with declaration fragments not 
consistently including "{ ... }" for anonymous TagDecls. To make testing these 
additions easier this patch fixes some text declaration fragments merging 
issues and updates tests accordingly.

>From f2755070ead054c56f7e9f9a2084ec40c10968bf Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 4 Apr 2024 18:33:25 +0100
Subject: [PATCH] [clang][ExtractAPI] Fix handling of anonymous TagDecls

This changes the handling of anonymous TagDecls to the following rules:
- If the TagDecl is embedded in the declaration for some VarDecl (this
  is the only possibility for RecordDecls), then pretend the child decls
  belong to the VarDecl
- If it's an EnumDecl proceed as we did previously, i.e., embed it in
  the enclosing DeclContext.

Additionally this fixes a few issues with declaration fragments not
consistently including "{ ... }" for anonymous TagDecls. To make testing
these additions easier this patch fixes some text declaration fragments
merging issues and updates tests accordingly.
---
 clang/include/clang/ExtractAPI/API.h  | 132 ++--
 clang/include/clang/ExtractAPI/APIRecords.inc |  16 +-
 .../clang/ExtractAPI/DeclarationFragments.h   |  84 ++-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  76 ++-
 clang/lib/ExtractAPI/API.cpp  |   8 +
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  17 +-
 .../Serialization/SymbolGraphSerializer.cpp   |   8 +
 .../ExtractAPI/anonymous_record_no_typedef.c  | 565 +-
 clang/test/ExtractAPI/enum.c  |  12 +-
 clang/test/ExtractAPI/function_noexcepts.cpp  |  18 +-
 clang/test/ExtractAPI/methods.cpp |   6 +-
 clang/test/ExtractAPI/objc_block.m|  48 +-
 .../ExtractAPI/typedef_anonymous_record.c |   4 +-
 clang/test/ExtractAPI/typedef_struct_enum.c   |   2 +-
 14 files changed, 427 insertions(+), 569 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 92cacf65c7d64e..05cfabd072a560 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -208,20 +208,20 @@ struct APIRecord {
 RK_ClassTemplate,
 RK_ClassTemplateSpecialization,
 RK_ClassTemplatePartialSpecialization,
-RK_LastRecordContext,
-RK_GlobalFunction,
-RK_GlobalFunctionTemplate,
-RK_GlobalFunctionTemplateSpecialization,
+RK_StructField,
+RK_UnionField,
+RK_CXXField,
+RK_StaticField,
+RK_CXXFieldTemplate,
 RK_GlobalVariable,
 RK_GlobalVariableTemplate,
 RK_GlobalVariableTemplateSpecialization,
 RK_GlobalVariableTemplatePartialSpecialization,
+RK_LastRecordContext,
+RK_GlobalFunction,
+RK_GlobalFunctionTemplate,
+RK_GlobalFunctionTemplateSpecialization,
 RK_EnumConstant,
-RK_StructField,
-RK_UnionField,
-RK_StaticField,
-RK_CXXField,
-RK_CXXFieldTemplate,
 RK_Concept,
 RK_CXXStaticMethod,
 RK_CXXInstanceMethod,
@@ -321,6 +321,8 @@ class RecordContext {
 
   RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
 
+  void stealRecordChain(RecordContext &Other);
+
   APIRecord::RecordKind getKind() const { return Kind; }
 
   struct record_iterator {
@@ -475,7 +477,7 @@ struct GlobalFunctionTemplateSpecializationRecord : 
GlobalFunctionRecord {
 };
 
 /// This holds information associated with global functions.
-struct GlobalVariableRecord : APIRecord {
+struct GlobalVariableRecord : APIRecord, RecordContext {
   GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
PresumedLoc Loc, AvailabilityInfo Availability,
LinkageInfo Linkage, const DocComment &Comment,
@@ -483,23 +485,28 @@ struct GlobalVariableRecord : APIRecord {
DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
   : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
   std::move(Availability), Linkage, Comment, Declaration,
-  SubHeading, IsFromSystemHeader) {}
+  SubHeading, IsFromSystemHeader),
+RecordContext(RK_GlobalVariable) {}
 
   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
-   SymbolReference Parent,
-
-   PresumedLoc Loc, AvailabilityInfo Availability,
-   LinkageInfo Linkage, const DocComment &Comment,
+   SymbolReference Parent, PresumedLoc Loc,
+   AvailabilityInfo Availability, Li

[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-04-02 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

Just reverted this due to buildbot failures in `Misc/warning-flags.c` will 
reenable shortly.

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


[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-04-02 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.


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


[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-04-02 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-03-27 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-03-26 Thread Daniel Grumberg via cfe-commits


@@ -119,20 +78,12 @@ static void 
WalkupFromMostDerivedType(LibClangExtractAPIVisitor &Visitor,
 break;
 #include "clang/AST/DeclNodes.inc"
   }
-
-  for (auto *Parent = D->getDeclContext(); Parent != nullptr;
-   Parent = Parent->getParent()) {
-if (WalkupParentContext(Parent, Visitor))

daniel-grumberg wrote:

Restore this logic for objc types?

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


[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-03-26 Thread Daniel Grumberg via cfe-commits


@@ -54,63 +55,21 @@ struct LibClangExtractAPIVisitor
 if (!shouldDeclBeIncluded(Decl))
   return true;
 
-const ObjCInterfaceDecl *Interface = Decl->getClassInterface();
-StringRef Name = Interface->getName();
-StringRef USR = API.recordUSR(Decl);
-PresumedLoc Loc =
-Context.getSourceManager().getPresumedLoc(Decl->getLocation());
-LinkageInfo Linkage = Decl->getLinkageAndVisibility();
-DocComment Comment;
-if (auto *RawComment = fetchRawCommentForDecl(Interface))
-  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
-  Context.getDiagnostics());
-
-// Build declaration fragments and sub-heading by generating them for the
-// interface.
-DeclarationFragments Declaration =
-DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Interface);
-DeclarationFragments SubHeading =
-DeclarationFragmentsBuilder::getSubHeading(Decl);
-
-// Collect super class information.
-SymbolReference SuperClass;
-if (const auto *SuperClassDecl = Decl->getSuperClass()) {
-  SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
-  SuperClass.USR = API.recordUSR(SuperClassDecl);
-}
-
-ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
-Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
-Comment, Declaration, SubHeading, SuperClass, isInSystemHeader(Decl));
-
-// Record all methods (selectors). This doesn't include automatically
-// synthesized property methods.
-recordObjCMethods(ObjCInterfaceRecord, Decl->methods());
-recordObjCProperties(ObjCInterfaceRecord, Decl->properties());
-recordObjCInstanceVariables(ObjCInterfaceRecord, Decl->ivars());
-
-return true;
+return VisitObjCInterfaceDecl(Decl->getClassInterface());

daniel-grumberg wrote:

Restore logic to grab symbols defined only in the implementation. First visit 
the interface and then add the things only defined in the implementation block 
to the interface record.

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


[clang] [clang][ExtractAPI] Add ability to create multiple symbol graphs (PR #86676)

2024-03-26 Thread Daniel Grumberg via cfe-commits


@@ -50,17 +51,20 @@ 
TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type,
   SmallString<128> TypeUSR;
   const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
   const TypedefType *TypedefTy = Type->getAs();
+  StringRef OwningModuleName;
 
   if (TypeDecl) {
 if (!TypedefTy)
   TypeName = TypeDecl->getName().str();
 
 clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
+if (auto *OwningModule = TypeDecl->getImportedOwningModule())
+  OwningModuleName = API.copyString(OwningModule->Name);
   } else {
 clang::index::generateUSRForType(Type, Context, TypeUSR);
   }
 
-  return {API.copyString(TypeName), API.copyString(TypeUSR)};
+  return {API.copyString(TypeName), API.copyString(TypeUSR), OwningModuleName};

daniel-grumberg wrote:

TODO: Can this be expressed as APISet.createSymbolReference

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


[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-03-26 Thread Daniel Grumberg via cfe-commits


@@ -1127,7 +1096,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
   .append("<", DeclarationFragments::FragmentKind::Text)
   .append(getFragmentsForTemplateArguments(
   Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
-  Decl->getTemplateParameters()->asArray()))
+  Decl->getTemplateArgsAsWritten()->arguments()))

daniel-grumberg wrote:

Looks like the right thing to me!

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


[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)

2024-01-22 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)

2024-01-22 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)

2024-01-22 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/77451

>From 8ff189e707a909f5228bce2042812a45a98d1e6c Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 9 Jan 2024 12:06:14 +
Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing
 mode

Ensure that we generate correct symbol kinds and declaration fragments
for unions in C and Objective-C parsing modes.

rdar://120544091
---
 clang/include/clang/ExtractAPI/API.h  |  48 +--
 .../clang/ExtractAPI/DeclarationFragments.h   |   5 +-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  42 ++-
 .../ExtractAPI/Serialization/SerializerBase.h |  12 +-
 .../Serialization/SymbolGraphSerializer.h |   4 +-
 clang/lib/ExtractAPI/API.cpp  |  35 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |   9 +-
 .../Serialization/SymbolGraphSerializer.cpp   |  18 +-
 clang/test/ExtractAPI/union.c | 281 ++
 9 files changed, 380 insertions(+), 74 deletions(-)
 create mode 100644 clang/test/ExtractAPI/union.c

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index f4a6374161685e2..0a0f1bd1e95f7fe 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -169,6 +169,7 @@ struct APIRecord {
 RK_Enum,
 RK_StructField,
 RK_Struct,
+RK_UnionField,
 RK_Union,
 RK_StaticField,
 RK_CXXField,
@@ -478,17 +479,19 @@ struct EnumRecord : APIRecord {
 };
 
 /// This holds information associated with struct fields.
-struct StructFieldRecord : APIRecord {
-  StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+struct RecordFieldRecord : APIRecord {
+  RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
 AvailabilityInfo Availability, const DocComment &Comment,
 DeclarationFragments Declaration,
-DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availability),
+DeclarationFragments SubHeading, RecordKind Kind,
+bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_StructField;
+return Record->getKind() == RK_StructField ||
+   Record->getKind() == RK_UnionField;
   }
 
 private:
@@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord {
 };
 
 /// This holds information associated with structs.
-struct StructRecord : APIRecord {
-  SmallVector> Fields;
+struct RecordRecord : APIRecord {
+  SmallVector> Fields;
 
-  StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
AvailabilityInfo Availability, const DocComment &Comment,
DeclarationFragments Declaration,
-   DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availability),
+   DeclarationFragments SubHeading, RecordKind Kind,
+   bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_Struct;
+return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
   }
 
 private:
@@ -1266,30 +1270,31 @@ class APISet {
   DeclarationFragments Declaration,
   DeclarationFragments SubHeading, bool 
IsFromSystemHeader);
 
-  /// Create and add a struct field record into the API set.
+  /// Create and add a record field record into the API set.
   ///
   /// Note: the caller is responsible for keeping the StringRef \p Name and
   /// \p USR alive. APISet::copyString provides a way to copy strings into
   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
   /// to generate the USR for \c D and keep it alive in APISet.
-  StructFieldRecord *
-  addStructField(StructRecord *Struct, StringRef Name, StringRef USR,
+  RecordFieldRecord *
+  addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
  PresumedLoc Loc, AvailabilityInfo Availability,
  const DocComment &Comment, DeclarationFragments Declaration,
- DeclarationFragments SubHeading, bool IsFromSystemHeader);
+ DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
+ bool IsFromSystemHeader);
 
-  /// Create and add a struct record into the API set.
+  /// Create and add a record record into the API set.
   ///
   /// Note: the

[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-19 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)

2024-01-18 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

That and the typedef case before the pointer case. The pointer check would lead 
to extraneous desugaring in the fragments, i.e. you would get something like 
`struct Bar * value`, because the typedefs are also pointer types and therefore 
the typedef name would get bypassed in favor of the form "PointeeType *"

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


[clang] [clang][ExtractAPI] Ensure typedef to pointer types are preserved (PR #78584)

2024-01-18 Thread Daniel Grumberg via cfe-commits

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

When generating declaration fragments for types that use typedefs to pointer 
types ensure that we keep the user-defined typedef form instead of desugaring 
the typedef.

rdar://102137655

>From d3c4ca8092fcec8c8ebea26826cdf7e724edf7a7 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 18 Jan 2024 13:13:13 +
Subject: [PATCH] [clang][ExtractAPI] Ensure typedef to pointer types are
 preserved

When generating declaration fragments for types that use typedefs to
pointer types ensure that we keep the user-defined typedef form instead
of desugaring the typedef.

rdar://102137655
---
 clang/lib/ExtractAPI/DeclarationFragments.cpp |  80 ++---
 clang/test/ExtractAPI/typedef.c   | 280 ++
 2 files changed, 320 insertions(+), 40 deletions(-)

diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index eb6eea0aaf5465..ae6b2eff5c8a29 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -252,6 +252,46 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 
   DeclarationFragments Fragments;
 
+  // An ElaboratedType is a sugar for types that are referred to using an
+  // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
+  // qualified name, e.g., `N::M::type`, or both.
+  if (const ElaboratedType *ET = dyn_cast(T)) {
+ElaboratedTypeKeyword Keyword = ET->getKeyword();
+if (Keyword != ElaboratedTypeKeyword::None) {
+  Fragments
+  .append(ElaboratedType::getKeywordName(Keyword),
+  DeclarationFragments::FragmentKind::Keyword)
+  .appendSpace();
+}
+
+if (const NestedNameSpecifier *NNS = ET->getQualifier())
+  Fragments.append(getFragmentsForNNS(NNS, Context, After));
+
+// After handling the elaborated keyword or qualified name, build
+// declaration fragments for the desugared underlying type.
+return Fragments.append(getFragmentsForType(ET->desugar(), Context, 
After));
+  }
+
+  // If the type is a typedefed type, get the underlying TypedefNameDecl for a
+  // direct reference to the typedef instead of the wrapped type.
+
+  // 'id' type is a typedef for an ObjCObjectPointerType
+  //  we treat it as a typedef
+  if (const TypedefType *TypedefTy = dyn_cast(T)) {
+const TypedefNameDecl *Decl = TypedefTy->getDecl();
+TypedefUnderlyingTypeResolver TypedefResolver(Context);
+std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
+
+if (T->isObjCIdType()) {
+  return Fragments.append(Decl->getName(),
+  DeclarationFragments::FragmentKind::Keyword);
+}
+
+return Fragments.append(
+Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier,
+USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0)));
+  }
+
   // Declaration fragments of a pointer type is the declaration fragments of
   // the pointee type followed by a `*`,
   if (T->isPointerType() && !T->isFunctionPointerType())
@@ -328,46 +368,6 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
 getFragmentsForType(AT->getElementType(), Context, After));
   }
 
-  // An ElaboratedType is a sugar for types that are referred to using an
-  // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
-  // qualified name, e.g., `N::M::type`, or both.
-  if (const ElaboratedType *ET = dyn_cast(T)) {
-ElaboratedTypeKeyword Keyword = ET->getKeyword();
-if (Keyword != ElaboratedTypeKeyword::None) {
-  Fragments
-  .append(ElaboratedType::getKeywordName(Keyword),
-  DeclarationFragments::FragmentKind::Keyword)
-  .appendSpace();
-}
-
-if (const NestedNameSpecifier *NNS = ET->getQualifier())
-  Fragments.append(getFragmentsForNNS(NNS, Context, After));
-
-// After handling the elaborated keyword or qualified name, build
-// declaration fragments for the desugared underlying type.
-return Fragments.append(getFragmentsForType(ET->desugar(), Context, 
After));
-  }
-
-  // If the type is a typedefed type, get the underlying TypedefNameDecl for a
-  // direct reference to the typedef instead of the wrapped type.
-
-  // 'id' type is a typedef for an ObjCObjectPointerType
-  //  we treat it as a typedef
-  if (const TypedefType *TypedefTy = dyn_cast(T)) {
-const TypedefNameDecl *Decl = TypedefTy->getDecl();
-TypedefUnderlyingTypeResolver TypedefResolver(Context);
-std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
-
-if (T->isObjCIdType()) {
-  return Fragments.append(Decl->getName(),
-  DeclarationFragments::FragmentKind::Keyword);
-}
-
-return Fragments.append(
-Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier,
-USR, TypedefResolver.g

[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-17 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.


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


[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-17 Thread Daniel Grumberg via cfe-commits


@@ -16,67 +16,61 @@
 #define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
 
 #include "clang/AST/Decl.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/VersionTuple.h"
 #include "llvm/Support/raw_ostream.h"
-
-using llvm::VersionTuple;
+#include 

daniel-grumberg wrote:

I don't think this is needed?

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


[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)

2024-01-11 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/77451

>From 9ed6ab49d39df12b95c65d48d065e82672dba48f Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 9 Jan 2024 12:06:14 +
Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing
 mode

Ensure that we generate correct symbol kinds and declaration fragments
for unions in C and Objective-C parsing modes.

rdar://120544091
---
 clang/include/clang/ExtractAPI/API.h  |  48 +--
 .../clang/ExtractAPI/DeclarationFragments.h   |   5 +-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  39 ++-
 .../ExtractAPI/Serialization/SerializerBase.h |  12 +-
 .../Serialization/SymbolGraphSerializer.h |   4 +-
 clang/lib/ExtractAPI/API.cpp  |  35 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |   9 +-
 .../Serialization/SymbolGraphSerializer.cpp   |  18 +-
 clang/test/ExtractAPI/union.c | 281 ++
 9 files changed, 378 insertions(+), 73 deletions(-)
 create mode 100644 clang/test/ExtractAPI/union.c

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index b4c0e0ad39cdf2..a86654dd64bec5 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -169,6 +169,7 @@ struct APIRecord {
 RK_Enum,
 RK_StructField,
 RK_Struct,
+RK_UnionField,
 RK_Union,
 RK_StaticField,
 RK_CXXField,
@@ -478,17 +479,19 @@ struct EnumRecord : APIRecord {
 };
 
 /// This holds information associated with struct fields.
-struct StructFieldRecord : APIRecord {
-  StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+struct RecordFieldRecord : APIRecord {
+  RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
 AvailabilitySet Availabilities, const DocComment &Comment,
 DeclarationFragments Declaration,
-DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities),
+DeclarationFragments SubHeading, RecordKind Kind,
+bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_StructField;
+return Record->getKind() == RK_StructField ||
+   Record->getKind() == RK_UnionField;
   }
 
 private:
@@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord {
 };
 
 /// This holds information associated with structs.
-struct StructRecord : APIRecord {
-  SmallVector> Fields;
+struct RecordRecord : APIRecord {
+  SmallVector> Fields;
 
-  StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
AvailabilitySet Availabilities, const DocComment &Comment,
DeclarationFragments Declaration,
-   DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities),
+   DeclarationFragments SubHeading, RecordKind Kind,
+   bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_Struct;
+return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
   }
 
 private:
@@ -1267,30 +1271,31 @@ class APISet {
   DeclarationFragments Declaration,
   DeclarationFragments SubHeading, bool 
IsFromSystemHeader);
 
-  /// Create and add a struct field record into the API set.
+  /// Create and add a record field record into the API set.
   ///
   /// Note: the caller is responsible for keeping the StringRef \p Name and
   /// \p USR alive. APISet::copyString provides a way to copy strings into
   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
   /// to generate the USR for \c D and keep it alive in APISet.
-  StructFieldRecord *
-  addStructField(StructRecord *Struct, StringRef Name, StringRef USR,
+  RecordFieldRecord *
+  addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
  PresumedLoc Loc, AvailabilitySet Availability,
  const DocComment &Comment, DeclarationFragments Declaration,
- DeclarationFragments SubHeading, bool IsFromSystemHeader);
+ DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
+ bool IsFromSystemHeader);
 
-  /// Create and add a struct record into the API set.
+  /// Create and add a record record into the API set.
   ///
   /// No

[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-01-11 Thread Daniel Grumberg via cfe-commits


@@ -196,8 +196,7 @@ template class Foo {};
   "spelling": "<"
 },
 {
-  "kind": "typeIdentifier",
-  "preciseIdentifier": "c:t0.0",
+  "kind": "genericArgument",

daniel-grumberg wrote:

might be best to leave these as generic text fragments

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


[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-09 Thread Daniel Grumberg via cfe-commits


@@ -1,50 +1,33 @@
 #include "clang/ExtractAPI/AvailabilityInfo.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 
 using namespace clang;
 using namespace extractapi;
 
-AvailabilitySet::AvailabilitySet(const Decl *Decl) {
-  // Collect availability attributes from all redeclrations.
-  for (const auto *RD : Decl->redecls()) {
-if (const auto *A = RD->getAttr()) {
-  if (!A->isImplicit()) {
-this->Availabilities.clear();
-UnconditionallyUnavailable = true;
-  }
-}
+AvailabilityInfo::AvailabilityInfo(const Decl *Decl) {

daniel-grumberg wrote:

I would prefer if this wasn't a constructor but rather a static type method of 
with signature:
```c++
AvailabilityInfo createFromDecl(const Decl *D);
```
that way you don't have to do line 19-21 in that way.

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


[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)

2024-01-09 Thread Daniel Grumberg via cfe-commits

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

Ensure that we generate correct symbol kinds and declaration fragments for 
unions in C and Objective-C parsing modes.

rdar://120544091

>From 23d0713ba8003731cf03d2226c2cb3000411554f Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Tue, 9 Jan 2024 12:06:14 +
Subject: [PATCH] [clang][ExtractAPI] Add support C unions in non C++ parsing
 mode

Ensure that we generate correct symbol kinds and declaration fragments
for unions in C and Objective-C parsing modes.

rdar://120544091
---
 clang/include/clang/ExtractAPI/API.h  |  46 +--
 .../clang/ExtractAPI/DeclarationFragments.h   |   5 +-
 .../clang/ExtractAPI/ExtractAPIVisitor.h  |  39 ++-
 .../ExtractAPI/Serialization/SerializerBase.h |  12 +-
 .../Serialization/SymbolGraphSerializer.h |   4 +-
 clang/lib/ExtractAPI/API.cpp  |  35 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp |   9 +-
 .../Serialization/SymbolGraphSerializer.cpp   |  18 +-
 clang/test/ExtractAPI/union.c | 281 ++
 9 files changed, 377 insertions(+), 72 deletions(-)
 create mode 100644 clang/test/ExtractAPI/union.c

diff --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index b4c0e0ad39cdf2..3bd3162da89a82 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -169,6 +169,7 @@ struct APIRecord {
 RK_Enum,
 RK_StructField,
 RK_Struct,
+RK_UnionField,
 RK_Union,
 RK_StaticField,
 RK_CXXField,
@@ -478,17 +479,19 @@ struct EnumRecord : APIRecord {
 };
 
 /// This holds information associated with struct fields.
-struct StructFieldRecord : APIRecord {
-  StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+struct RecordFieldRecord : APIRecord {
+  RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
 AvailabilitySet Availabilities, const DocComment &Comment,
 DeclarationFragments Declaration,
-DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities),
+DeclarationFragments SubHeading, RecordKind Kind,
+bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_StructField;
+return Record->getKind() == RK_StructField ||
+   Record->getKind() == RK_UnionField;
   }
 
 private:
@@ -496,19 +499,20 @@ struct StructFieldRecord : APIRecord {
 };
 
 /// This holds information associated with structs.
-struct StructRecord : APIRecord {
-  SmallVector> Fields;
+struct RecordRecord : APIRecord {
+  SmallVector> Fields;
 
-  StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
AvailabilitySet Availabilities, const DocComment &Comment,
DeclarationFragments Declaration,
-   DeclarationFragments SubHeading, bool IsFromSystemHeader)
-  : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities),
+   DeclarationFragments SubHeading, RecordKind Kind,
+   bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
   static bool classof(const APIRecord *Record) {
-return Record->getKind() == RK_Struct;
+return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
   }
 
 private:
@@ -1267,17 +1271,18 @@ class APISet {
   DeclarationFragments Declaration,
   DeclarationFragments SubHeading, bool 
IsFromSystemHeader);
 
-  /// Create and add a struct field record into the API set.
+  /// Create and add a record field record into the API set.
   ///
   /// Note: the caller is responsible for keeping the StringRef \p Name and
   /// \p USR alive. APISet::copyString provides a way to copy strings into
   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
   /// to generate the USR for \c D and keep it alive in APISet.
-  StructFieldRecord *
-  addStructField(StructRecord *Struct, StringRef Name, StringRef USR,
+  RecordFieldRecord *
+  addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
  PresumedLoc Loc, AvailabilitySet Availability,
  const DocComment &Comment, DeclarationFragments Declaration,
- DeclarationFragments SubHeading, bool IsFromSystemHeader);
+ DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
+ bool IsFromSystemH

[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-05 Thread Daniel Grumberg via cfe-commits


@@ -256,14 +256,14 @@ struct APIRecord {
   APIRecord() = delete;
 
   APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
-PresumedLoc Location, AvailabilitySet Availabilities,
+PresumedLoc Location, const AvailabilityInfo &Availability,

daniel-grumberg wrote:

Can you keep this as a value and bring back the `std::move` below, this allows 
to prevent unnecessary copies.

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


[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-05 Thread Daniel Grumberg via cfe-commits


@@ -61,17 +61,17 @@ APISet::addNamespace(APIRecord *Parent, StringRef Name, 
StringRef USR,
 
 GlobalVariableRecord *
 APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
- AvailabilitySet Availabilities, LinkageInfo Linkage,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
  const DocComment &Comment, DeclarationFragments Fragments,
  DeclarationFragments SubHeading, bool IsFromSystemHeader) 
{
   return addTopLevelRecord(USRBasedLookupTable, GlobalVariables, USR, Name, 
Loc,
-   std::move(Availabilities), Linkage, Comment,
-   Fragments, SubHeading, IsFromSystemHeader);
+   Availability, Linkage, Comment, Fragments,

daniel-grumberg wrote:

Can you make sure that all of Availabilities are `std::move`

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


[clang] [clang][ExtractAPI] Record availability information only for the target platform (PR #76823)

2024-01-05 Thread Daniel Grumberg via cfe-commits


@@ -45,7 +45,7 @@ RecordTy *addTopLevelRecord(DenseMap 
&USRLookupTable,
 
 NamespaceRecord *
 APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR,
- PresumedLoc Loc, AvailabilitySet Availability,
+ PresumedLoc Loc, const AvailabilityInfo &Availability,

daniel-grumberg wrote:

Can we keep these as plain values (i.e. just `AvailabilityInfo Availability`), 
this prevents the move operation below and leads to a copy. Additionally, this 
prevents copy ellision with how we pass the parameters in.

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


[clang] [clang][ExtractAPI] Allow serialization for ObjC++ headers (PR #74733)

2023-12-07 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Allow serialization for ObjC++ headers (PR #74733)

2023-12-07 Thread Daniel Grumberg via cfe-commits

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

rdar://79874441

>From 87d6b0fca621bae69102161fa4c3ebc003ae27bc Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Thu, 7 Dec 2023 14:52:47 +
Subject: [PATCH] [clang][ExtractAPI] Allow serialization for ObjC++ headers

rdar://79874441
---
 .../Serialization/SymbolGraphSerializer.cpp   |   3 +-
 clang/test/ExtractAPI/language.c  | 101 +-
 2 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 931933b2bd1ac..d9675b0c94de3 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -199,9 +199,10 @@ StringRef getLanguageName(Language Lang) {
 return "objective-c";
   case Language::CXX:
 return "c++";
+  case Language::ObjCXX:
+return "objective-c++";
 
   // Unsupported language currently
-  case Language::ObjCXX:
   case Language::OpenCL:
   case Language::OpenCLCXX:
   case Language::CUDA:
diff --git a/clang/test/ExtractAPI/language.c b/clang/test/ExtractAPI/language.c
index 6facd18f5d981..fe98626c84613 100644
--- a/clang/test/ExtractAPI/language.c
+++ b/clang/test/ExtractAPI/language.c
@@ -4,29 +4,42 @@
 // RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json
 // RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
 // RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json
+// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
+// RUN: %t/objcpp.reference.output.json.in >> %t/objcpp.reference.output.json
 
-// RUN: %clang -extract-api -x c-header -target arm64-apple-macosx \
+// RUN: %clang_cc1 -extract-api -x c-header -triple arm64-apple-macosx \
 // RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s
-// RUN: %clang -extract-api -x objective-c-header -target arm64-apple-macosx \
+// RUN: %clang_cc1 -extract-api -x objective-c-header -triple 
arm64-apple-macosx \
 // RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s
+// RUN: %clang_cc1 -extract-api -x objective-c++-header -triple 
arm64-apple-macosx \
+// RUN: %t/objcpp.h -o %t/objcpp.output.json | FileCheck -allow-empty %s
 
 // Generator version is not consistent across test runs, normalize it.
 // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
 // RUN: %t/c.output.json >> %t/c.output-normalized.json
 // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
 // RUN: %t/objc.output.json >> %t/objc.output-normalized.json
+// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
+// RUN: %t/objcpp.output.json >> %t/objcpp.output-normalized.json
 
 // RUN: diff %t/c.reference.output.json %t/c.output-normalized.json
 // RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json
+// RUN: diff %t/objcpp.reference.output.json %t/objcpp.output-normalized.json
 
 // CHECK-NOT: error:
 // CHECK-NOT: warning:
 
 //--- c.h
 char c;
+///expected-no-diagnostics
 
 //--- objc.h
 char objc;
+///expected-no-diagnostics
+
+//--- objcpp.h
+char objcpp;
+///expected-no-diagnostics
 
 //--- c.reference.output.json.in
 {
@@ -196,3 +209,87 @@ char objc;
 }
   ]
 }
+//--- objcpp.reference.output.json.in
+{
+  "metadata": {
+"formatVersion": {
+  "major": 0,
+  "minor": 5,
+  "patch": 3
+},
+"generator": "?"
+  },
+  "module": {
+"name": "",
+"platform": {
+  "architecture": "arm64",
+  "operatingSystem": {
+"minimumVersion": {
+  "major": 11,
+  "minor": 0,
+  "patch": 0
+},
+"name": "macosx"
+  },
+  "vendor": "apple"
+}
+  },
+  "relationships": [],
+  "symbols": [
+{
+  "accessLevel": "public",
+  "declarationFragments": [
+{
+  "kind": "typeIdentifier",
+  "preciseIdentifier": "c:C",
+  "spelling": "char"
+},
+{
+  "kind": "text",
+  "spelling": " "
+},
+{
+  "kind": "identifier",
+  "spelling": "objcpp"
+},
+{
+  "kind": "text",
+  "spelling": ";"
+}
+  ],
+  "identifier": {
+"interfaceLanguage": "objective-c++",
+"precise": "c:@objcpp"
+  },
+  "kind": {
+"displayName": "Global Variable",
+"identifier": "objective-c++.var"
+  },
+  "location": {
+"position": {
+  "character": 5,
+  "line": 0
+},
+"uri": "file://INPUT_DIR/objcpp.h"
+  },
+  "names": {
+"navigator": [
+  {
+"kind": "identifier",
+"spelling": "objcpp"
+  }
+],
+"subHeading": [
+  {
+"kind": "identifier",
+"spelling": "objcpp"
+  }
+],
+"title": "objcpp"
+  },
+  "pathCompon

[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)

2023-12-01 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)

2023-12-01 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

Awesome! Let me know if you need any clarification as the semantic is now 
different from what it was originally and what it was after your patch.

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


[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)

2023-12-01 Thread Daniel Grumberg via cfe-commits

daniel-grumberg wrote:

Adding @compnerd since he committed (on behalf of someone else) the patch that 
caused this subtle problem in the first place. Do you know the original authors 
handle on GitHub?

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


[clang] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to traverse VFS when determining file path (PR #74071)

2023-12-01 Thread Daniel Grumberg via cfe-commits

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

As part of https://reviews.llvm.org/D154130 the logic of LocationFileChecker 
changed slightly to try and get the absolute external file path instead of the 
name as requested when the file was openened which would be before VFS mappings 
in our usage. Ensure that we only check against the name as requested instead 
of trying to generate the external canonical file path.

rdar://115195433

>From 93f1bb149011be424ea2383ea21c99ba1ed595c8 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Fri, 1 Dec 2023 12:19:38 +
Subject: [PATCH] [clang][ExtractAPI] Ensure LocationFileChecker doesn't try to
 traverse VFS when determining file path

As part of https://reviews.llvm.org/D154130 the logic of LocationFileChecker
changed slightly to try and get the absolute external file path instead of the
name as requested when the file was openened which would be before VFS mappings
in our usage. Ensure that we only check against the name as requested instead of
trying to generate the external canonical file path.

rdar://115195433
---
 clang/lib/ExtractAPI/ExtractAPIConsumer.cpp   |  11 +-
 .../test/ExtractAPI/vfs_redirected_include.m  | 211 ++
 2 files changed, 219 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/ExtractAPI/vfs_redirected_include.m

diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp 
b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 3aba3bf44547cf6..fe282dfb19e8aa7 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/FileEntry.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -167,6 +168,12 @@ std::optional getRelativeIncludeName(const 
CompilerInstance &CI,
   return std::nullopt;
 }
 
+std::optional getRelativeIncludeName(const CompilerInstance &CI,
+  FileEntryRef FE,
+  bool *IsQuoted = nullptr) {
+  return getRelativeIncludeName(CI, FE.getNameAsRequested(), IsQuoted);
+}
+
 struct LocationFileChecker {
   bool operator()(SourceLocation Loc) {
 // If the loc refers to a macro expansion we need to first get the file
@@ -187,11 +194,9 @@ struct LocationFileChecker {
 if (ExternalFileEntries.count(*File))
   return false;
 
-StringRef FileName = SM.getFileManager().getCanonicalName(*File);
-
 // Try to reduce the include name the same way we tried to include it.
 bool IsQuoted = false;
-if (auto IncludeName = getRelativeIncludeName(CI, FileName, &IsQuoted))
+if (auto IncludeName = getRelativeIncludeName(CI, *File, &IsQuoted))
   if (llvm::any_of(KnownFiles,
[&IsQuoted, &IncludeName](const auto &KnownFile) {
  return KnownFile.first.equals(*IncludeName) &&
diff --git a/clang/test/ExtractAPI/vfs_redirected_include.m 
b/clang/test/ExtractAPI/vfs_redirected_include.m
new file mode 100644
index 000..9ba7e1dedb601eb
--- /dev/null
+++ b/clang/test/ExtractAPI/vfs_redirected_include.m
@@ -0,0 +1,211 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Setup framework root
+// RUN: mkdir -p %t/Frameworks/MyFramework.framework/Headers
+// RUN: cp %t/MyFramework.h %t/Frameworks/MyFramework.framework/Headers/
+// RUN: cp %t/MyHeader.h %t/Frameworks/MyFramework.framework/Headers/
+
+// RUN: sed -e "s@SRCROOT@%{/t:regex_replacement}@g" \
+// RUN: %t/reference.output.json.in >> %t/reference.output.json
+
+// Create VFS overlay from framework headers to SRCROOT
+// RUN: sed -e "s@SRCROOT@%{/t:regex_replacement}@g" -e 
"s@DSTROOT@%{/t:regex_replacement}@g" \
+// RUN: %t/vfsoverlay.yaml.in >> %t/vfsoverlay.yaml
+
+// Input headers use paths to the framework root/DSTROOT
+// RUN: %clang_cc1 -extract-api -v --product-name=MyFramework \
+// RUN: -triple arm64-apple-macosx \
+// RUN: -iquote%t -ivfsoverlay %t/vfsoverlay.yaml -F%t/Frameworks \
+// RUN: -x objective-c-header \
+// RUN: %t/Frameworks/MyFramework.framework/Headers/MyFramework.h \
+// RUN: %t/Frameworks/MyFramework.framework/Headers/MyHeader.h \
+// RUN: %t/QuotedHeader.h \
+// RUN: -o %t/output.json 2>&1 -verify | FileCheck -allow-empty %s
+
+// Generator version is not consistent across test runs, normalize it.
+// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
+// RUN: %t/output.json >> %t/output-normalized.json
+// RUN: diff %t/reference.output.json %t/output-normalized.json
+
+// CHECK:  :
+// CHECK-NEXT: #import 
+// CHECK-NEXT: #import 
+// CHECK-NEXT: #import "QuotedHeader.h"
+
+//--- vfsoverlay.yaml.in
+{
+"case-sensitive": "false",
+"roots": [
+{
+"contents": [
+{
+"external-

[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-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 

[clang] ExtractAPI: use zero-based indices for line/column in symbol graph (PR #71753)

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

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


[clang] ExtractAPI: use zero-based indices for line/column in symbol graph (PR #71753)

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

https://github.com/daniel-grumberg approved this pull request.

LGTM!

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


[clang] [clang][ExtractAPI] Update availability serialization in SGF (PR #71418)

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

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


[clang] [clang][ExtractAPI] Update availability serialization in SGF (PR #71418)

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

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

The prevailiing symbol graph parsing library expects availability attributes to 
just be "introduced" instead of "introducedVersion"

rdar://117823923

>From ad0c6afb7c728b2ea8ad83be22d670808d319783 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Mon, 6 Nov 2023 16:51:35 +
Subject: [PATCH] [clang][ExtractAPI] Update availability serialization in SGF

The prevailiing symbol graph parsing library expects availability
attributes to just be "introduced" instead of "introducedVersion"

rdar://117823923
---
 .../Serialization/SymbolGraphSerializer.cpp   |  6 +++---
 clang/test/ExtractAPI/availability.c  | 20 +--
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp 
b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 3c8668d26c60b76..f757522ef8e49db 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -177,11 +177,11 @@ serializeAvailability(const AvailabilitySet 
&Availabilities) {
 if (AvailInfo.Unavailable)
   Availability["isUnconditionallyUnavailable"] = true;
 else {
-  serializeObject(Availability, "introducedVersion",
+  serializeObject(Availability, "introduced",
   serializeSemanticVersion(AvailInfo.Introduced));
-  serializeObject(Availability, "deprecatedVersion",
+  serializeObject(Availability, "deprecated",
   serializeSemanticVersion(AvailInfo.Deprecated));
-  serializeObject(Availability, "obsoletedVersion",
+  serializeObject(Availability, "obsoleted",
   serializeSemanticVersion(AvailInfo.Obsoleted));
 }
 AvailabilityArray.emplace_back(std::move(Availability));
diff --git a/clang/test/ExtractAPI/availability.c 
b/clang/test/ExtractAPI/availability.c
index 0c8cd3629f3fdee..5e3890df83563d4 100644
--- a/clang/test/ExtractAPI/availability.c
+++ b/clang/test/ExtractAPI/availability.c
@@ -127,7 +127,7 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
   "availability": [
 {
   "domain": "macos",
-  "introducedVersion": {
+  "introduced": {
 "major": 12,
 "minor": 0,
 "patch": 0
@@ -200,18 +200,18 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
   "accessLevel": "public",
   "availability": [
 {
-  "deprecatedVersion": {
+  "deprecated": {
 "major": 12,
 "minor": 0,
 "patch": 0
   },
   "domain": "macos",
-  "introducedVersion": {
+  "introduced": {
 "major": 11,
 "minor": 0,
 "patch": 0
   },
-  "obsoletedVersion": {
+  "obsoleted": {
 "major": 20,
 "minor": 0,
 "patch": 0
@@ -284,18 +284,18 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
   "accessLevel": "public",
   "availability": [
 {
-  "deprecatedVersion": {
+  "deprecated": {
 "major": 12,
 "minor": 0,
 "patch": 0
   },
   "domain": "macos",
-  "introducedVersion": {
+  "introduced": {
 "major": 11,
 "minor": 0,
 "patch": 0
   },
-  "obsoletedVersion": {
+  "obsoleted": {
 "major": 20,
 "minor": 0,
 "patch": 0
@@ -303,7 +303,7 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
 },
 {
   "domain": "ios",
-  "introducedVersion": {
+  "introduced": {
 "major": 13,
 "minor": 0,
 "patch": 0
@@ -311,7 +311,7 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
 },
 {
   "domain": "tvos",
-  "introducedVersion": {
+  "introduced": {
 "major": 15,
 "minor": 0,
 "patch": 0
@@ -389,7 +389,7 @@ void e(void) __attribute__((availability(tvos, 
unavailable)));
 },
 {
   "domain": "macos",
-  "introducedVersion": {
+  "introduced": {
 "major": 11,
 "minor": 0,
 "patch": 0

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-10-26 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

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

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/65481

>From d5054bcc53dad87232a4969e1a1f978b8d5a593d Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 6 Sep 2023 12:20:30 +0100
Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site

For declarations declared inside a macro, e.g.:
```
`#define MAKE_FUNC(suffix) \
 /// Not selected doc comment \
 void func_##suffix(void) {  }

/// Doc comment foo
MAKE_FUNC(foo)

/// Doc comment bar
MAKE_FUNC(bar)


Prefer the doc comment at the expansion site instead of the one defined
in the macro.

rdar://113995729
---
 clang/lib/AST/ASTContext.cpp   | 197 -
 clang/test/Index/annotate-comments-objc.m  |  48 +++--
 clang/unittests/Tooling/SourceCodeTest.cpp |   8 +-
 3 files changed, 102 insertions(+), 151 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 27a675b83211775..72faea11349b48c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -112,10 +112,10 @@ enum FloatingRank {
   Ibm128Rank
 };
 
-/// \returns location that is relevant when searching for Doc comments related
-/// to \p D.
-static SourceLocation getDeclLocForCommentSearch(const Decl *D,
- SourceManager &SourceMgr) {
+/// \returns The locations that are relevant when searching for Doc comments
+/// related to \p D.
+static SmallVector
+getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) {
   assert(D);
 
   // User can not attach documentation to implicit declarations.
@@ -167,115 +167,48 @@ static SourceLocation getDeclLocForCommentSearch(const 
Decl *D,
   isa(D))
 return {};
 
+  SmallVector Locations;
   // Find declaration location.
   // For Objective-C declarations we generally don't expect to have multiple
   // declarators, thus use declaration starting location as the "declaration
   // location".
   // For all other declarations multiple declarators are used quite frequently,
   // so we use the location of the identifier as the "declaration location".
+  SourceLocation BaseLocation;
   if (isa(D) || isa(D) ||
-  isa(D) ||
-  isa(D) ||
+  isa(D) || isa(D) ||
   isa(D) ||
   // Allow association with Y across {} in `typedef struct X {} Y`.
   isa(D))
-return D->getBeginLoc();
+BaseLocation = D->getBeginLoc();
+  else
+BaseLocation = D->getLocation();
 
-  const SourceLocation DeclLoc = D->getLocation();
-  if (DeclLoc.isMacroID()) {
-// There are (at least) three types of macros we care about here.
-//
-// 1. Macros that are used in the definition of a type outside the macro,
-//with a comment attached at the macro call site.
-//```
-//#define MAKE_NAME(Foo) Name##Foo
-//
-///// Comment is here, where we use the macro.
-//struct MAKE_NAME(Foo) {
-//int a;
-//int b;
-//};
-//```
-// 2. Macros that define whole things along with the comment.
-//```
-//#define MAKE_METHOD(name) \
-//  /** Comment is here, inside the macro. */ \
-//  void name() {}
-//
-//struct S {
-//  MAKE_METHOD(f)
-//}
-//```
-// 3. Macros that both declare a type and name a decl outside the macro.
-//```
-///// Comment is here, where we use the macro.
-//typedef NS_ENUM(NSInteger, Size) {
-//SizeWidth,
-//SizeHeight
-//};
-//```
-//In this case NS_ENUM declares am enum type, and uses the same name 
for
-//the typedef declaration that appears outside the macro. The comment
-//here should be applied to both declarations inside and outside the
-//macro.
-//
-// We have found a Decl name that comes from inside a macro, but
-// Decl::getLocation() returns the place where the macro is being called.
-// If the declaration (and not just the name) resides inside the macro,
-// then we want to map Decl::getLocation() into the macro to where the
-// declaration and its attached comment (if any) were written.
-//
-// This mapping into the macro is done by mapping the location to its
-// spelling location, however even if the declaration is inside a macro,
-// the name's spelling can come from a macro argument (case 2 above). In
-// this case mapping the location to the spelling location finds the
-// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not
-// where the declaration and its comment are located.
-//
-// To avoid this issue, we make use of Decl::getBeginLocation() instead.
-// While the declaration's position is where the name is written, the
-// comment is always attached to the begining of the declaration, not to
-// the name.
-//
-// In the first case, the begin location of the

[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-10-23 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/65481

>From e9be513c357d7bb01a3acf69871e2e9889cb2079 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 6 Sep 2023 12:20:30 +0100
Subject: [PATCH] [clang] Prioritze decl comments from macro expansion site

For declarations declared inside a macro, e.g.:
```
`#define MAKE_FUNC(suffix) \
 /// Not selected doc comment \
 void func_##suffix(void) {  }

/// Doc comment foo
MAKE_FUNC(foo)

/// Doc comment bar
MAKE_FUNC(bar)


Prefer the doc comment at the expansion site instead of the one defined
in the macro.

rdar://113995729
---
 clang/lib/AST/ASTContext.cpp   | 197 -
 clang/test/Index/annotate-comments-objc.m  |  41 +++--
 clang/unittests/Tooling/SourceCodeTest.cpp |   8 +-
 3 files changed, 95 insertions(+), 151 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 27a675b83211775..72faea11349b48c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -112,10 +112,10 @@ enum FloatingRank {
   Ibm128Rank
 };
 
-/// \returns location that is relevant when searching for Doc comments related
-/// to \p D.
-static SourceLocation getDeclLocForCommentSearch(const Decl *D,
- SourceManager &SourceMgr) {
+/// \returns The locations that are relevant when searching for Doc comments
+/// related to \p D.
+static SmallVector
+getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) {
   assert(D);
 
   // User can not attach documentation to implicit declarations.
@@ -167,115 +167,48 @@ static SourceLocation getDeclLocForCommentSearch(const 
Decl *D,
   isa(D))
 return {};
 
+  SmallVector Locations;
   // Find declaration location.
   // For Objective-C declarations we generally don't expect to have multiple
   // declarators, thus use declaration starting location as the "declaration
   // location".
   // For all other declarations multiple declarators are used quite frequently,
   // so we use the location of the identifier as the "declaration location".
+  SourceLocation BaseLocation;
   if (isa(D) || isa(D) ||
-  isa(D) ||
-  isa(D) ||
+  isa(D) || isa(D) ||
   isa(D) ||
   // Allow association with Y across {} in `typedef struct X {} Y`.
   isa(D))
-return D->getBeginLoc();
+BaseLocation = D->getBeginLoc();
+  else
+BaseLocation = D->getLocation();
 
-  const SourceLocation DeclLoc = D->getLocation();
-  if (DeclLoc.isMacroID()) {
-// There are (at least) three types of macros we care about here.
-//
-// 1. Macros that are used in the definition of a type outside the macro,
-//with a comment attached at the macro call site.
-//```
-//#define MAKE_NAME(Foo) Name##Foo
-//
-///// Comment is here, where we use the macro.
-//struct MAKE_NAME(Foo) {
-//int a;
-//int b;
-//};
-//```
-// 2. Macros that define whole things along with the comment.
-//```
-//#define MAKE_METHOD(name) \
-//  /** Comment is here, inside the macro. */ \
-//  void name() {}
-//
-//struct S {
-//  MAKE_METHOD(f)
-//}
-//```
-// 3. Macros that both declare a type and name a decl outside the macro.
-//```
-///// Comment is here, where we use the macro.
-//typedef NS_ENUM(NSInteger, Size) {
-//SizeWidth,
-//SizeHeight
-//};
-//```
-//In this case NS_ENUM declares am enum type, and uses the same name 
for
-//the typedef declaration that appears outside the macro. The comment
-//here should be applied to both declarations inside and outside the
-//macro.
-//
-// We have found a Decl name that comes from inside a macro, but
-// Decl::getLocation() returns the place where the macro is being called.
-// If the declaration (and not just the name) resides inside the macro,
-// then we want to map Decl::getLocation() into the macro to where the
-// declaration and its attached comment (if any) were written.
-//
-// This mapping into the macro is done by mapping the location to its
-// spelling location, however even if the declaration is inside a macro,
-// the name's spelling can come from a macro argument (case 2 above). In
-// this case mapping the location to the spelling location finds the
-// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not
-// where the declaration and its comment are located.
-//
-// To avoid this issue, we make use of Decl::getBeginLocation() instead.
-// While the declaration's position is where the name is written, the
-// comment is always attached to the begining of the declaration, not to
-// the name.
-//
-// In the first case, the begin location of the 

[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-10-23 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg updated 
https://github.com/llvm/llvm-project/pull/65481

>From 32155e8b5ac01242c3e16968f9a7c821d16b7007 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg 
Date: Wed, 6 Sep 2023 12:20:30 +0100
Subject: [PATCH 1/2] [clang] Prioritze decl comments from macro expansion site

For declarations declared inside a macro, e.g.:
```
`#define MAKE_FUNC(suffix) \
 /// Not selected doc comment \
 void func_##suffix(void) {  }

/// Doc comment foo
MAKE_FUNC(foo)

/// Doc comment bar
MAKE_FUNC(bar)


Prefer the doc comment at the expansion site instead of the one defined
in the macro.

rdar://113995729
---
 clang/lib/AST/ASTContext.cpp   | 191 +++--
 clang/test/Index/annotate-comments-objc.m  |  12 +-
 clang/unittests/Tooling/SourceCodeTest.cpp |   5 +-
 3 files changed, 70 insertions(+), 138 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4b1d9e86797b778..074f59bd5a50411 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -112,10 +112,10 @@ enum FloatingRank {
   Ibm128Rank
 };
 
-/// \returns location that is relevant when searching for Doc comments related
-/// to \p D.
-static SourceLocation getDeclLocForCommentSearch(const Decl *D,
- SourceManager &SourceMgr) {
+/// \returns The locations that are relevant when searching for Doc comments
+/// related to \p D.
+static SmallVector
+getDeclLocsForCommentSearch(const Decl *D, SourceManager &SourceMgr) {
   assert(D);
 
   // User can not attach documentation to implicit declarations.
@@ -167,115 +167,41 @@ static SourceLocation getDeclLocForCommentSearch(const 
Decl *D,
   isa(D))
 return {};
 
+  SmallVector Locations;
   // Find declaration location.
   // For Objective-C declarations we generally don't expect to have multiple
   // declarators, thus use declaration starting location as the "declaration
   // location".
   // For all other declarations multiple declarators are used quite frequently,
   // so we use the location of the identifier as the "declaration location".
+  SourceLocation BaseLocation;
   if (isa(D) || isa(D) ||
-  isa(D) ||
-  isa(D) ||
+  isa(D) || isa(D) ||
   isa(D) ||
   // Allow association with Y across {} in `typedef struct X {} Y`.
   isa(D))
-return D->getBeginLoc();
+BaseLocation = D->getBeginLoc();
+  else
+BaseLocation = D->getLocation();
 
-  const SourceLocation DeclLoc = D->getLocation();
-  if (DeclLoc.isMacroID()) {
-// There are (at least) three types of macros we care about here.
-//
-// 1. Macros that are used in the definition of a type outside the macro,
-//with a comment attached at the macro call site.
-//```
-//#define MAKE_NAME(Foo) Name##Foo
-//
-///// Comment is here, where we use the macro.
-//struct MAKE_NAME(Foo) {
-//int a;
-//int b;
-//};
-//```
-// 2. Macros that define whole things along with the comment.
-//```
-//#define MAKE_METHOD(name) \
-//  /** Comment is here, inside the macro. */ \
-//  void name() {}
-//
-//struct S {
-//  MAKE_METHOD(f)
-//}
-//```
-// 3. Macros that both declare a type and name a decl outside the macro.
-//```
-///// Comment is here, where we use the macro.
-//typedef NS_ENUM(NSInteger, Size) {
-//SizeWidth,
-//SizeHeight
-//};
-//```
-//In this case NS_ENUM declares am enum type, and uses the same name 
for
-//the typedef declaration that appears outside the macro. The comment
-//here should be applied to both declarations inside and outside the
-//macro.
-//
-// We have found a Decl name that comes from inside a macro, but
-// Decl::getLocation() returns the place where the macro is being called.
-// If the declaration (and not just the name) resides inside the macro,
-// then we want to map Decl::getLocation() into the macro to where the
-// declaration and its attached comment (if any) were written.
-//
-// This mapping into the macro is done by mapping the location to its
-// spelling location, however even if the declaration is inside a macro,
-// the name's spelling can come from a macro argument (case 2 above). In
-// this case mapping the location to the spelling location finds the
-// argument's position (at `f` in MAKE_METHOD(`f`) above), which is not
-// where the declaration and its comment are located.
-//
-// To avoid this issue, we make use of Decl::getBeginLocation() instead.
-// While the declaration's position is where the name is written, the
-// comment is always attached to the begining of the declaration, not to
-// the name.
-//
-// In the first case, the begin location of the

[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-09-20 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-09-20 Thread Daniel Grumberg via cfe-commits


@@ -374,11 +374,10 @@ TEST(SourceCodeTest, getAssociatedRangeWithComments) {
 
   // Does not include comments when only the decl or the comment come from a
   // macro.

daniel-grumberg wrote:

Good spot, can't believe I removed the FIXME and not the comment explaining the 
FIXME 😵‍💫 

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


[clang] [clang] Prioritze decl comments from macro expansion site (PR #65481)

2023-09-08 Thread Daniel Grumberg via cfe-commits

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


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Daniel Grumberg via cfe-commits

https://github.com/daniel-grumberg approved this pull request.

LGTM

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


  1   2   >