Skip to content

Commit 3e4e2d1

Browse files
don't collect bases for types without definitions
rdar://123430367
1 parent d83501f commit 3e4e2d1

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

clang/include/clang/ExtractAPI/ExtractAPIVisitor.h

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,28 +175,30 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
175175
SmallVector<SymbolReference> getBases(const CXXRecordDecl *Decl) {
176176
// FIXME: store AccessSpecifier given by inheritance
177177
SmallVector<SymbolReference> Bases;
178-
for (const auto &BaseSpecifier : Decl->bases()) {
179-
// skip classes not inherited as public
180-
if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
181-
continue;
182-
if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
183-
Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
184-
} else {
185-
SymbolReference BaseClass;
186-
BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
187-
Decl->getASTContext().getPrintingPolicy()));
188-
189-
if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
190-
if (auto *TTPTD = BaseSpecifier.getType()
191-
->getAs<TemplateTypeParmType>()
192-
->getDecl()) {
193-
SmallString<128> USR;
194-
index::generateUSRForDecl(TTPTD, USR);
195-
BaseClass.USR = API.copyString(USR);
196-
BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
178+
if (Decl->isCompleteDefinition()) {
179+
for (const auto &BaseSpecifier : Decl->bases()) {
180+
// skip classes not inherited as public
181+
if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
182+
continue;
183+
if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
184+
Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
185+
} else {
186+
SymbolReference BaseClass;
187+
BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
188+
Decl->getASTContext().getPrintingPolicy()));
189+
190+
if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
191+
if (auto *TTPTD = BaseSpecifier.getType()
192+
->getAs<TemplateTypeParmType>()
193+
->getDecl()) {
194+
SmallString<128> USR;
195+
index::generateUSRForDecl(TTPTD, USR);
196+
BaseClass.USR = API.copyString(USR);
197+
BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
198+
}
197199
}
200+
Bases.emplace_back(BaseClass);
198201
}
199-
Bases.emplace_back(BaseClass);
200202
}
201203
}
202204
return Bases;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,21 @@ class MyClass {
1313
my_vec myVec;
1414
};
1515

16+
struct OuterStruct {
17+
struct InnerStruct;
18+
int outer_field;
19+
};
20+
1621
// RUN: c-index-test -single-symbol-sgf-at=%s:13:13 local %s | FileCheck --check-prefix=CHECK-MYVEC %s
1722
// CHECK-MYVEC: "parentContexts":[{"kind":"c++.class","name":"MyClass","usr":"c:@S@MyClass"},{"kind":"c++.property","name":"myVec","usr":"c:@S@MyClass@FI@myVec"}]
1823
// CHECK-MYVEC: "identifier":{"interfaceLanguage":"c++","precise":"c:@S@MyClass@FI@myVec"}
1924
// CHECK-MYVEC: "kind":{"displayName":"Instance Property","identifier":"c++.property"}
2025
// CHECK-MYVEC: "title":"myVec"
2126
// CHECK-MYVEC: "pathComponents":["MyClass","myVec"]
27+
28+
// RUN: c-index-test -single-symbol-sgf-at=%s:17:17 local %s | FileCheck --check-prefix=CHECK-INNER %s
29+
// CHECK-INNER: "parentContexts":[{"kind":"c++.struct","name":"OuterStruct","usr":"c:@S@OuterStruct"},{"kind":"c++.struct","name":"InnerStruct","usr":"c:@S@OuterStruct@S@InnerStruct"}]
30+
// CHECK-INNER: "identifier":{"interfaceLanguage":"c++","precise":"c:@S@OuterStruct@S@InnerStruct"}
31+
// CHECK-INNER: "kind":{"displayName":"Structure","identifier":"c++.struct"}
32+
// CHECK-INNER: "title":"InnerStruct"
33+
// CHECK-INNER: "pathComponents":["OuterStruct","InnerStruct"]

0 commit comments

Comments
 (0)