Skip to content

Commit 7a0ff00

Browse files
[clang] [extract-api] Don't crash for category in libclang APIs
Remove failure conditions for categories in libclang and return empty content instead. Differential Revision: https://reviews.llvm.org/D142101
1 parent 34096e4 commit 7a0ff00

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ bool generatePathComponents(
484484
SmallVector<PathComponent, 4> ReverseComponenents;
485485
ReverseComponenents.emplace_back(Record.USR, Record.Name, Record.getKind());
486486
const auto *CurrentParent = &Record.ParentInformation;
487+
bool FailedToFindParent = false;
487488
while (CurrentParent && !CurrentParent->empty()) {
488489
PathComponent CurrentParentComponent(CurrentParent->ParentUSR,
489490
CurrentParent->ParentName,
@@ -506,8 +507,10 @@ bool generatePathComponents(
506507

507508
// The parent record doesn't exist which means the symbol shouldn't be
508509
// treated as part of the current product.
509-
if (!ParentRecord)
510-
return true;
510+
if (!ParentRecord) {
511+
FailedToFindParent = true;
512+
break;
513+
}
511514

512515
ReverseComponenents.push_back(std::move(CurrentParentComponent));
513516
CurrentParent = &ParentRecord->ParentInformation;
@@ -516,8 +519,9 @@ bool generatePathComponents(
516519
for (const auto &PC : reverse(ReverseComponenents))
517520
ComponentTransformer(PC);
518521

519-
return false;
522+
return FailedToFindParent;
520523
}
524+
521525
Object serializeParentContext(const PathComponent &PC, Language Lang) {
522526
Object ParentContextElem;
523527
ParentContextElem["usr"] = PC.USR;
@@ -530,12 +534,15 @@ template <typename RecordTy>
530534
Array generateParentContexts(const RecordTy &Record, const APISet &API,
531535
Language Lang) {
532536
Array ParentContexts;
533-
if (generatePathComponents(
534-
Record, API, [Lang, &ParentContexts](const PathComponent &PC) {
535-
ParentContexts.push_back(serializeParentContext(PC, Lang));
536-
}))
537-
ParentContexts.clear();
538-
ParentContexts.pop_back();
537+
generatePathComponents(Record, API,
538+
[Lang, &ParentContexts](const PathComponent &PC) {
539+
ParentContexts.push_back(
540+
serializeParentContext(PC, Lang));
541+
});
542+
543+
// The last component would be the record itself so let's remove it.
544+
if (!ParentContexts.empty())
545+
ParentContexts.pop_back();
539546

540547
return ParentContexts;
541548
}
@@ -862,6 +869,9 @@ SymbolGraphSerializer::serializeSingleSymbolSGF(StringRef USR,
862869
if (!Record)
863870
return {};
864871

872+
if (isa<ObjCCategoryRecord>(Record))
873+
return {};
874+
865875
Object Root;
866876
APIIgnoresList EmptyIgnores;
867877
SymbolGraphSerializer Serializer(API, EmptyIgnores,

clang/test/Index/extract-api-cursor.m

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ @interface Derived: Base
2525
- (void)derivedMethodWithValue:(id<Protocol>)value;
2626
@end
2727

28+
/// This won't show up in docs because we can't serialize it
29+
@interface Derived ()
30+
/// Derived method in category docs, won't show up either.
31+
- (void)derivedMethodInCategory;
32+
@end
33+
2834
// RUN: c-index-test -single-symbol-sgfs local %s | FileCheck %s
2935

3036
// Checking for Foo
@@ -53,7 +59,7 @@ - (void)derivedMethodWithValue:(id<Protocol>)value;
5359

5460
// Checking for baseProperty
5561
// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
56-
// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
62+
// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
5763
// CHECK-SAME: "isSystem":false
5864
// CHECK-SAME: "usr":"c:@S@Foo"}]
5965
// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base"
@@ -63,7 +69,7 @@ - (void)derivedMethodWithValue:(id<Protocol>)value;
6369

6470
// Checking for baseMethodWithArg
6571
// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
66-
// CHECK-SAME:"relatedSymbols":[]
72+
// CHECK-SAME: "relatedSymbols":[]
6773
// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base"
6874
// CHECK-SAME: "text":"Base method docs"
6975
// CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
@@ -79,7 +85,7 @@ - (void)derivedMethodWithValue:(id<Protocol>)value;
7985

8086
// Checking for protocolProperty
8187
// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.protocol","name":"Protocol","usr":"c:objc(pl)Protocol"}]
82-
// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
88+
// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
8389
// CHECK-SAME: "isSystem":false
8490
// CHECK-SAME: "usr":"c:@S@Foo"}]
8591
// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(pl)Protocol(py)protocolProperty","target":"c:objc(pl)Protocol"
@@ -89,7 +95,7 @@ - (void)derivedMethodWithValue:(id<Protocol>)value;
8995

9096
// Checking for Derived
9197
// CHECK-NEXT: "parentContexts":[]
92-
// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
98+
// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
9399
// CHECK-SAME: "isSystem":false
94100
// CHECK-SAME: "usr":"c:objc(cs)Base"}]
95101
// CHECK-SAME: "relationships":[{"kind":"inheritsFrom","source":"c:objc(cs)Derived","target":"c:objc(cs)Base"
@@ -99,8 +105,11 @@ - (void)derivedMethodWithValue:(id<Protocol>)value;
99105

100106
// Checking for derivedMethodWithValue
101107
// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Derived","usr":"c:objc(cs)Derived"}]
102-
// CHECK-SAME:"relatedSymbols":[]
108+
// CHECK-SAME: "relatedSymbols":[]
103109
// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)derivedMethodWithValue:","target":"c:objc(cs)Derived"
104110
// CHECK-SAME: "text":"Derived method docs"
105111
// CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
106112
// CHECK-SAME: "title":"derivedMethodWithValue:"
113+
114+
// CHECK-NOT: This won't show up in docs because we can't serialize it
115+
// CHECK-NOT: Derived method in category docs, won't show up either.

0 commit comments

Comments
 (0)