Skip to content

Commit 1b7631a

Browse files
authored
[clang-doc] Improve clang-doc performance through memoization (#96809)
1 parent fe8d1e6 commit 1b7631a

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

clang-tools-extra/clang-doc/Mapper.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,28 @@
1212
#include "clang/AST/Comment.h"
1313
#include "clang/Index/USRGeneration.h"
1414
#include "llvm/ADT/StringExtras.h"
15-
#include "llvm/Support/Error.h"
15+
#include "llvm/ADT/StringSet.h"
16+
#include "llvm/Support/Mutex.h"
1617

1718
namespace clang {
1819
namespace doc {
1920

21+
static llvm::StringSet<> USRVisited;
22+
static llvm::sys::Mutex USRVisitedGuard;
23+
24+
template <typename T> bool isTypedefAnonRecord(const T *D) {
25+
if (const auto *C = dyn_cast<CXXRecordDecl>(D)) {
26+
return C->getTypedefNameForAnonDecl();
27+
}
28+
return false;
29+
}
30+
2031
void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
2132
TraverseDecl(Context.getTranslationUnitDecl());
2233
}
2334

24-
template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
35+
template <typename T>
36+
bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
2537
// If we're looking a decl not in user files, skip this decl.
2638
if (D->getASTContext().getSourceManager().isInSystemHeader(D->getLocation()))
2739
return true;
@@ -34,6 +46,16 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
3446
// If there is an error generating a USR for the decl, skip this decl.
3547
if (index::generateUSRForDecl(D, USR))
3648
return true;
49+
// Prevent Visiting USR twice
50+
{
51+
std::lock_guard<llvm::sys::Mutex> Guard(USRVisitedGuard);
52+
StringRef Visited = USR.str();
53+
if (USRVisited.count(Visited) && !isTypedefAnonRecord<T>(D))
54+
return true;
55+
// We considered a USR to be visited only when its defined
56+
if (IsDefinition)
57+
USRVisited.insert(Visited);
58+
}
3759
bool IsFileInRootDir;
3860
llvm::SmallString<128> File =
3961
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
@@ -53,30 +75,34 @@ template <typename T> bool MapASTVisitor::mapDecl(const T *D) {
5375
}
5476

5577
bool MapASTVisitor::VisitNamespaceDecl(const NamespaceDecl *D) {
56-
return mapDecl(D);
78+
return mapDecl(D, /*isDefinition=*/true);
5779
}
5880

59-
bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) { return mapDecl(D); }
81+
bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) {
82+
return mapDecl(D, D->isThisDeclarationADefinition());
83+
}
6084

61-
bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) { return mapDecl(D); }
85+
bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) {
86+
return mapDecl(D, D->isThisDeclarationADefinition());
87+
}
6288

6389
bool MapASTVisitor::VisitCXXMethodDecl(const CXXMethodDecl *D) {
64-
return mapDecl(D);
90+
return mapDecl(D, D->isThisDeclarationADefinition());
6591
}
6692

6793
bool MapASTVisitor::VisitFunctionDecl(const FunctionDecl *D) {
6894
// Don't visit CXXMethodDecls twice
6995
if (isa<CXXMethodDecl>(D))
7096
return true;
71-
return mapDecl(D);
97+
return mapDecl(D, D->isThisDeclarationADefinition());
7298
}
7399

74100
bool MapASTVisitor::VisitTypedefDecl(const TypedefDecl *D) {
75-
return mapDecl(D);
101+
return mapDecl(D, /*isDefinition=*/true);
76102
}
77103

78104
bool MapASTVisitor::VisitTypeAliasDecl(const TypeAliasDecl *D) {
79-
return mapDecl(D);
105+
return mapDecl(D, /*isDefinition=*/true);
80106
}
81107

82108
comments::FullComment *

clang-tools-extra/clang-doc/Mapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
4343
bool VisitTypeAliasDecl(const TypeAliasDecl *D);
4444

4545
private:
46-
template <typename T> bool mapDecl(const T *D);
46+
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
4747

4848
int getLine(const NamedDecl *D, const ASTContext &Context) const;
4949
llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context,

clang-tools-extra/clang-doc/tool/ClangDocMain.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ Example usage for a project using a compile commands database:
303303
for (auto &Group : USRToBitcode) {
304304
Pool.async([&]() {
305305
std::vector<std::unique_ptr<doc::Info>> Infos;
306-
307306
for (auto &Bitcode : Group.getValue()) {
308307
llvm::BitstreamCursor Stream(Bitcode);
309308
doc::ClangDocBitcodeReader Reader(Stream);

0 commit comments

Comments
 (0)