[llvm-branch-commits] [clang-tools-extra] [clang-doc] Handle static members and functions (PR #135457)
Paul Kirth via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Apr 12 09:43:13 PDT 2025
https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/135457
>From 1e5adae44b8e8ebbb0438d1c5972f3937711954a Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Mon, 7 Apr 2025 08:37:40 -0700
Subject: [PATCH 1/3] [clang-doc] Handle static members and functions
clang-doc didn't visit VarDecl, and hence never collected info
from class statics members and functions.
Fixes #59813.
---
clang-tools-extra/clang-doc/Mapper.cpp | 4 ++
clang-tools-extra/clang-doc/Mapper.h | 1 +
clang-tools-extra/clang-doc/Serialize.cpp | 56 +++++++++++++++++++
clang-tools-extra/clang-doc/Serialize.h | 4 ++
.../test/clang-doc/basic-project.test | 22 +++++++-
5 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 6c90db03424c6..98698f9151280 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -82,6 +82,10 @@ bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) {
return mapDecl(D, D->isThisDeclarationADefinition());
}
+bool MapASTVisitor::VisitVarDecl(const VarDecl *D) {
+ return mapDecl(D, D->isThisDeclarationADefinition());
+}
+
bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) {
return mapDecl(D, D->isThisDeclarationADefinition());
}
diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h
index 75c8e947c8f90..62fc5fbbdf3da 100644
--- a/clang-tools-extra/clang-doc/Mapper.h
+++ b/clang-tools-extra/clang-doc/Mapper.h
@@ -36,6 +36,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
void HandleTranslationUnit(ASTContext &Context) override;
bool VisitNamespaceDecl(const NamespaceDecl *D);
bool VisitRecordDecl(const RecordDecl *D);
+ bool VisitVarDecl(const VarDecl *D);
bool VisitEnumDecl(const EnumDecl *D);
bool VisitCXXMethodDecl(const CXXMethodDecl *D);
bool VisitFunctionDecl(const FunctionDecl *D);
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index f737fc75135a1..d34451cd10484 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -729,6 +729,62 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
return {std::move(I), std::move(Parent)};
}
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const VarDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+ auto I = std::make_unique<RecordInfo>();
+ bool IsInAnonymousNamespace = false;
+ populateSymbolInfo(*I, D, FC, LineNumber, File, IsFileInRootDir,
+ IsInAnonymousNamespace);
+ if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
+ return {};
+
+ I->Path = getInfoRelativePath(I->Namespace);
+
+ PopulateTemplateParameters(I->Template, D);
+
+ // Full and partial specializations.
+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ if (!I->Template)
+ I->Template.emplace();
+ I->Template->Specialization.emplace();
+ auto &Specialization = *I->Template->Specialization;
+
+ // What this is a specialization of.
+ auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
+ if (auto *CTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
+ Specialization.SpecializationOf = getUSRForDecl(CTD);
+ else if (auto *CTPSD =
+ dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
+ Specialization.SpecializationOf = getUSRForDecl(CTPSD);
+
+ // Parameters to the specilization. For partial specializations, get the
+ // parameters "as written" from the ClassTemplatePartialSpecializationDecl
+ // because the non-explicit template parameters will have generated internal
+ // placeholder names rather than the names the user typed that match the
+ // template parameters.
+ if (const ClassTemplatePartialSpecializationDecl *CTPSD =
+ dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
+ if (const ASTTemplateArgumentListInfo *AsWritten =
+ CTPSD->getTemplateArgsAsWritten()) {
+ for (unsigned i = 0; i < AsWritten->getNumTemplateArgs(); i++) {
+ Specialization.Params.emplace_back(
+ getSourceCode(D, (*AsWritten)[i].getSourceRange()));
+ }
+ }
+ } else {
+ for (const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
+ Specialization.Params.push_back(TemplateArgumentToInfo(D, Arg));
+ }
+ }
+ }
+
+ // Records are inserted into the parent by reference, so we need to return
+ // both the parent and the record itself.
+ auto Parent = MakeAndInsertIntoParent<const RecordInfo &>(*I);
+ return {std::move(I), std::move(Parent)};
+}
+
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
diff --git a/clang-tools-extra/clang-doc/Serialize.h b/clang-tools-extra/clang-doc/Serialize.h
index 4e203ca7891ac..41946796f39f6 100644
--- a/clang-tools-extra/clang-doc/Serialize.h
+++ b/clang-tools-extra/clang-doc/Serialize.h
@@ -52,6 +52,10 @@ std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
StringRef File, bool IsFileInRootDir, bool PublicOnly);
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const VarDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool IsFileInRootDir, bool PublicOnly);
+
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
StringRef File, bool IsFileInRootDir, bool PublicOnly);
diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test
index 6b6d512329c30..e9fd49b4f3f93 100644
--- a/clang-tools-extra/test/clang-doc/basic-project.test
+++ b/clang-tools-extra/test/clang-doc/basic-project.test
@@ -52,7 +52,15 @@
// JSON-INDEX-NEXT: "Name": "Calculator",
// JSON-INDEX-NEXT: "RefType": "record",
// JSON-INDEX-NEXT: "Path": "GlobalNamespace",
-// JSON-INDEX-NEXT: "Children": []
+// JSON-INDEX-NEXT: "Children": [
+// JSON-INDEX-NEXT: {
+// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
+// JSON-INDEX-NEXT: "Name": "static_val",
+// JSON-INDEX-NEXT: "RefType": "record",
+// JSON-INDEX-NEXT: "Path": "GlobalNamespace/Calculator",
+// JSON-INDEX-NEXT: "Children": []
+// JSON-INDEX-NEXT: }
+// JSON-INDEX-NEXT: ]
// JSON-INDEX-NEXT: },
// JSON-INDEX-NEXT: {
// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
@@ -135,6 +143,9 @@
// HTML-CALC: <p> Holds a public value.</p>
// HTML-CALC: <div>public int public_val</div>
+// HTML-CALC: <h2 id="Records">Records</h2>
+// HTML-CALC: <a href="../GlobalNamespace/Calculator/static_val.html">static_val</a>
+
// HTML-CALC: <h2 id="Functions">Functions</h2>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3>
// HTML-CALC: <p>public int add(int a, int b)</p>
@@ -324,6 +335,8 @@
// MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8*
// MD-CALC: **brief** A simple calculator class.
// MD-CALC: Provides basic arithmetic operations.
+// MD-CALC: ## Members
+// MD-CALC: public int public_val
// MD-CALC: ## Functions
// MD-CALC: ### add
// MD-CALC: *public int add(int a, int b)*
@@ -354,6 +367,13 @@
// MD-CALC: **b** Second integer.
// MD-CALC: **return** double The result of a / b.
// MD-CALC: **throw**if b is zero.
+// MD-CALC: ### mod
+// MD-CALC: *public int mod(int a, int b)*
+// MD-CALC: *Defined at ./include/Calculator.h#54*
+// MD-CALC: **brief** Performs the mod operation on integers.
+// MD-CALC: **a** First integer.
+// MD-CALC: **b** Second integer.
+// MD-CALC: **return** The result of a % b.
// MD-CIRCLE: # class Circle
// MD-CIRCLE: *Defined at .{{[\/]}}include{{[\/]}}Circle.h#10*
>From c99d100db177993258cf1353e8b6697e8695e40b Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Fri, 11 Apr 2025 22:05:42 -0700
Subject: [PATCH 2/3] Fix typo
---
clang-tools-extra/clang-doc/Serialize.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index d34451cd10484..34aaa60c4db85 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -702,7 +702,7 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
Specialization.SpecializationOf = getUSRForDecl(CTPSD);
- // Parameters to the specilization. For partial specializations, get the
+ // Parameters to the specialization. For partial specializations, get the
// parameters "as written" from the ClassTemplatePartialSpecializationDecl
// because the non-explicit template parameters will have generated internal
// placeholder names rather than the names the user typed that match the
>From 7f7d14fe0708c6c0eed4db1f8284b5f5d4048a1f Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Sat, 12 Apr 2025 09:42:04 -0700
Subject: [PATCH 3/3] Fix file separator in test for Windows
---
clang-tools-extra/test/clang-doc/basic-project.test | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test
index e9fd49b4f3f93..b679705cc0b24 100644
--- a/clang-tools-extra/test/clang-doc/basic-project.test
+++ b/clang-tools-extra/test/clang-doc/basic-project.test
@@ -57,7 +57,7 @@
// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
// JSON-INDEX-NEXT: "Name": "static_val",
// JSON-INDEX-NEXT: "RefType": "record",
-// JSON-INDEX-NEXT: "Path": "GlobalNamespace/Calculator",
+// JSON-INDEX-NEXT: "Path": "GlobalNamespace{{[\/]}}Calculator",
// JSON-INDEX-NEXT: "Children": []
// JSON-INDEX-NEXT: }
// JSON-INDEX-NEXT: ]
More information about the llvm-branch-commits
mailing list