Skip to content

Commit 8e3909e

Browse files
[clang][ExtractAPI] Implement Record removal from APISet
rdar://128092236
1 parent b6d1df2 commit 8e3909e

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

clang/include/clang/ExtractAPI/API.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,13 @@
1919
#define LLVM_CLANG_EXTRACTAPI_API_H
2020

2121
#include "clang/AST/Availability.h"
22-
#include "clang/AST/Decl.h"
2322
#include "clang/AST/DeclBase.h"
24-
#include "clang/AST/DeclObjC.h"
2523
#include "clang/AST/RawCommentList.h"
2624
#include "clang/Basic/SourceLocation.h"
27-
#include "clang/Basic/Specifiers.h"
2825
#include "clang/ExtractAPI/DeclarationFragments.h"
29-
#include "llvm/ADT/ArrayRef.h"
30-
#include "llvm/ADT/MapVector.h"
31-
#include "llvm/ADT/StringRef.h"
26+
#include "llvm/ADT/SmallPtrSet.h"
3227
#include "llvm/Support/Allocator.h"
3328
#include "llvm/Support/Casting.h"
34-
#include "llvm/Support/Compiler.h"
35-
#include "llvm/Support/ErrorHandling.h"
36-
#include "llvm/Support/raw_ostream.h"
3729
#include "llvm/TargetParser/Triple.h"
3830
#include <cstddef>
3931
#include <iterator>
@@ -328,6 +320,8 @@ class RecordContext {
328320
/// chain.
329321
void stealRecordChain(RecordContext &Other);
330322

323+
void removeFromRecordChain(APIRecord *Record);
324+
331325
APIRecord::RecordKind getKind() const { return Kind; }
332326

333327
struct record_iterator {
@@ -1426,10 +1420,14 @@ class APISet {
14261420
typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
14271421
createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
14281422

1429-
ArrayRef<const APIRecord *> getTopLevelRecords() const {
1430-
return TopLevelRecords;
1423+
auto getTopLevelRecords() const {
1424+
return llvm::iterator_range<decltype(TopLevelRecords)::iterator>(TopLevelRecords);
14311425
}
14321426

1427+
void removeRecord(StringRef USR);
1428+
1429+
void removeRecord(APIRecord *Record);
1430+
14331431
APISet(const llvm::Triple &Target, Language Lang,
14341432
const std::string &ProductName)
14351433
: Target(Target), Lang(Lang), ProductName(ProductName) {}
@@ -1456,7 +1454,7 @@ class APISet {
14561454
// lives in the BumpPtrAllocator.
14571455
using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
14581456
llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
1459-
std::vector<const APIRecord *> TopLevelRecords;
1457+
llvm::SmallPtrSet<const APIRecord *, 32> TopLevelRecords;
14601458

14611459
public:
14621460
const std::string ProductName;
@@ -1482,7 +1480,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
14821480
dyn_cast_if_present<RecordContext>(Record->Parent.Record))
14831481
ParentContext->addToRecordChain(Record);
14841482
else
1485-
TopLevelRecords.push_back(Record);
1483+
TopLevelRecords.insert(Record);
14861484
} else {
14871485
Record = dyn_cast<RecordTy>(Result.first->second.get());
14881486
}

clang/lib/ExtractAPI/API.cpp

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "clang/ExtractAPI/API.h"
16-
#include "clang/AST/RawCommentList.h"
17-
#include "clang/Index/USRGeneration.h"
1816
#include "llvm/ADT/StringRef.h"
1917
#include "llvm/Support/ErrorHandling.h"
2018
#include <memory>
@@ -60,6 +58,10 @@ bool RecordContext::IsWellFormed() const {
6058

6159
void RecordContext::stealRecordChain(RecordContext &Other) {
6260
assert(IsWellFormed());
61+
// Other's record chain is empty, nothing to do
62+
if (Other.First == nullptr && Other.Last == nullptr)
63+
return;
64+
6365
// If we don't have an empty chain append Other's chain into ours.
6466
if (First)
6567
Last->NextInContext = Other.First;
@@ -68,6 +70,9 @@ void RecordContext::stealRecordChain(RecordContext &Other) {
6870

6971
Last = Other.Last;
7072

73+
for (auto *StolenRecord = Other.First; StolenRecord != nullptr; StolenRecord = StolenRecord->getNextInContext())
74+
StolenRecord->Parent = SymbolReference(cast<APIRecord>(this));
75+
7176
// Delete Other's chain to ensure we don't accidentally traverse it.
7277
Other.First = nullptr;
7378
Other.Last = nullptr;
@@ -85,6 +90,22 @@ void RecordContext::addToRecordChain(APIRecord *Record) const {
8590
Last = Record;
8691
}
8792

93+
void RecordContext::removeFromRecordChain(APIRecord *Record) {
94+
APIRecord *Prev = nullptr;
95+
for (APIRecord *Curr = First; Curr != Record; Curr = Curr->NextInContext)
96+
Prev = Curr;
97+
98+
if (Prev)
99+
Prev->NextInContext = Record->NextInContext;
100+
else
101+
First = Record->NextInContext;
102+
103+
if (Last == Record)
104+
Last = Prev;
105+
106+
Record->NextInContext = nullptr;
107+
}
108+
88109
APIRecord *APISet::findRecordForUSR(StringRef USR) const {
89110
if (USR.empty())
90111
return nullptr;
@@ -114,6 +135,38 @@ SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR,
114135
return SymbolReference(copyString(Name), copyString(USR), copyString(Source));
115136
}
116137

138+
139+
void APISet::removeRecord(StringRef USR) {
140+
auto Result = USRBasedLookupTable.find(USR);
141+
if (Result != USRBasedLookupTable.end()) {
142+
auto *Record = Result->getSecond().get();
143+
auto &ParentReference= Record->Parent;
144+
auto *ParentRecord = const_cast<APIRecord *>(ParentReference.Record);
145+
if (!ParentRecord)
146+
ParentRecord = findRecordForUSR(ParentReference.USR);
147+
148+
if (auto *ParentCtx = llvm::cast_if_present<RecordContext>(ParentRecord)) {
149+
ParentCtx->removeFromRecordChain(Record);
150+
if (auto *RecordAsCtx=
151+
llvm::dyn_cast<RecordContext>(Record))
152+
ParentCtx->stealRecordChain(*RecordAsCtx);
153+
} else {
154+
TopLevelRecords.erase(Record);
155+
if (auto *RecordAsCtx=
156+
llvm::dyn_cast<RecordContext>(Record)) {
157+
for (const auto *Child = RecordAsCtx->First; Child != nullptr;
158+
Child = Child->getNextInContext())
159+
TopLevelRecords.insert(Child);
160+
}
161+
}
162+
USRBasedLookupTable.erase(Result);
163+
}
164+
}
165+
166+
void APISet::removeRecord(APIRecord *Record) {
167+
removeRecord(Record->USR);
168+
}
169+
117170
APIRecord::~APIRecord() {}
118171
TagRecord::~TagRecord() {}
119172
RecordRecord::~RecordRecord() {}

0 commit comments

Comments
 (0)