Skip to content

Commit 4b02fd4

Browse files
committed
[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.
1 parent 07c9c87 commit 4b02fd4

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ bool MapASTVisitor::VisitRecordDecl(const RecordDecl *D) {
8282
return mapDecl(D, D->isThisDeclarationADefinition());
8383
}
8484

85+
bool MapASTVisitor::VisitVarDecl(const VarDecl *D) {
86+
return mapDecl(D, D->isThisDeclarationADefinition());
87+
}
88+
8589
bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) {
8690
return mapDecl(D, D->isThisDeclarationADefinition());
8791
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
3636
void HandleTranslationUnit(ASTContext &Context) override;
3737
bool VisitNamespaceDecl(const NamespaceDecl *D);
3838
bool VisitRecordDecl(const RecordDecl *D);
39+
bool VisitVarDecl(const VarDecl *D);
3940
bool VisitEnumDecl(const EnumDecl *D);
4041
bool VisitCXXMethodDecl(const CXXMethodDecl *D);
4142
bool VisitFunctionDecl(const FunctionDecl *D);

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,62 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
729729
return {std::move(I), std::move(Parent)};
730730
}
731731

732+
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
733+
emitInfo(const VarDecl *D, const FullComment *FC, int LineNumber,
734+
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
735+
auto I = std::make_unique<RecordInfo>();
736+
bool IsInAnonymousNamespace = false;
737+
populateSymbolInfo(*I, D, FC, LineNumber, File, IsFileInRootDir,
738+
IsInAnonymousNamespace);
739+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
740+
return {};
741+
742+
I->Path = getInfoRelativePath(I->Namespace);
743+
744+
PopulateTemplateParameters(I->Template, D);
745+
746+
// Full and partial specializations.
747+
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
748+
if (!I->Template)
749+
I->Template.emplace();
750+
I->Template->Specialization.emplace();
751+
auto &Specialization = *I->Template->Specialization;
752+
753+
// What this is a specialization of.
754+
auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
755+
if (auto *CTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
756+
Specialization.SpecializationOf = getUSRForDecl(CTD);
757+
else if (auto *CTPSD =
758+
dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
759+
Specialization.SpecializationOf = getUSRForDecl(CTPSD);
760+
761+
// Parameters to the specilization. For partial specializations, get the
762+
// parameters "as written" from the ClassTemplatePartialSpecializationDecl
763+
// because the non-explicit template parameters will have generated internal
764+
// placeholder names rather than the names the user typed that match the
765+
// template parameters.
766+
if (const ClassTemplatePartialSpecializationDecl *CTPSD =
767+
dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
768+
if (const ASTTemplateArgumentListInfo *AsWritten =
769+
CTPSD->getTemplateArgsAsWritten()) {
770+
for (unsigned i = 0; i < AsWritten->getNumTemplateArgs(); i++) {
771+
Specialization.Params.emplace_back(
772+
getSourceCode(D, (*AsWritten)[i].getSourceRange()));
773+
}
774+
}
775+
} else {
776+
for (const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
777+
Specialization.Params.push_back(TemplateArgumentToInfo(D, Arg));
778+
}
779+
}
780+
}
781+
782+
// Records are inserted into the parent by reference, so we need to return
783+
// both the parent and the record itself.
784+
auto Parent = MakeAndInsertIntoParent<const RecordInfo &>(*I);
785+
return {std::move(I), std::move(Parent)};
786+
}
787+
732788
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
733789
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
734790
llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
5252
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
5353
StringRef File, bool IsFileInRootDir, bool PublicOnly);
5454

55+
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
56+
emitInfo(const VarDecl *D, const FullComment *FC, int LineNumber,
57+
StringRef File, bool IsFileInRootDir, bool PublicOnly);
58+
5559
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
5660
emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
5761
StringRef File, bool IsFileInRootDir, bool PublicOnly);

clang-tools-extra/test/clang-doc/basic-project.test

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@
5252
// JSON-INDEX-NEXT: "Name": "Calculator",
5353
// JSON-INDEX-NEXT: "RefType": "record",
5454
// JSON-INDEX-NEXT: "Path": "GlobalNamespace",
55-
// JSON-INDEX-NEXT: "Children": []
55+
// JSON-INDEX-NEXT: "Children": [
56+
// JSON-INDEX-NEXT: {
57+
// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
58+
// JSON-INDEX-NEXT: "Name": "static_val",
59+
// JSON-INDEX-NEXT: "RefType": "record",
60+
// JSON-INDEX-NEXT: "Path": "GlobalNamespace/Calculator",
61+
// JSON-INDEX-NEXT: "Children": []
62+
// JSON-INDEX-NEXT: }
63+
// JSON-INDEX-NEXT: ]
5664
// JSON-INDEX-NEXT: },
5765
// JSON-INDEX-NEXT: {
5866
// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
@@ -135,6 +143,9 @@
135143
// HTML-CALC: <p> Holds a public value.</p>
136144
// HTML-CALC: <div>public int public_val</div>
137145

146+
// HTML-CALC: <h2 id="Records">Records</h2>
147+
// HTML-CALC: <a href="../GlobalNamespace/Calculator/static_val.html">static_val</a>
148+
138149
// HTML-CALC: <h2 id="Functions">Functions</h2>
139150
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3>
140151
// HTML-CALC: <p>public int add(int a, int b)</p>
@@ -192,12 +203,12 @@
192203
// HTML-CALC: <p>if b is zero.</p>
193204

194205
// HTML-CALC: <p>public int mod(int a, int b)</p>
195-
// CALC-NO-REPOSITORY: Defined at line 20 of file .{{.}}src{{.}}Calculator.cpp
206+
// CALC-NO-REPOSITORY: Defined at line 54 of file .{{.}}include{{.}}Calculator.h
196207
// CALC-REPOSITORY: Defined at line
197-
// CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp#20">20</a>
198-
// CALC-LINE-PREFIX: <a href="https://repository.com/./src/Calculator.cpp#L20">20</a>
208+
// CALC-REPOSITORY-NEXT: <a href="https://repository.com/./include/Calculator.h#54">54</a>
209+
// CALC-LINE-PREFIX: <a href="https://repository.com/./include/Calculator.h#L54">54</a>
199210
// CALC-REPOSITORY-NEXT: of file
200-
// CALC-REPOSITORY-NEXT: <a href="https://repository.com/./src/Calculator.cpp">Calculator.cpp</a>
211+
// CALC-REPOSITORY-NEXT: <a href="https://repository.com/./include/Calculator.h">Calculator.h</a>
201212
// HTML-CALC: <div>brief</div>
202213
// HTML-CALC: <p> Performs the mod operation on integers.</p>
203214
// HTML-CALC: <div>return</div>
@@ -324,6 +335,8 @@
324335
// MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8*
325336
// MD-CALC: **brief** A simple calculator class.
326337
// MD-CALC: Provides basic arithmetic operations.
338+
// MD-CALC: ## Members
339+
// MD-CALC: public int public_val
327340
// MD-CALC: ## Functions
328341
// MD-CALC: ### add
329342
// MD-CALC: *public int add(int a, int b)*
@@ -354,6 +367,13 @@
354367
// MD-CALC: **b** Second integer.
355368
// MD-CALC: **return** double The result of a / b.
356369
// MD-CALC: **throw**if b is zero.
370+
// MD-CALC: ### mod
371+
// MD-CALC: *public int mod(int a, int b)*
372+
// MD-CALC: *Defined at ./include/Calculator.h#54*
373+
// MD-CALC: **brief** Performs the mod operation on integers.
374+
// MD-CALC: **a** First integer.
375+
// MD-CALC: **b** Second integer.
376+
// MD-CALC: **return** The result of a % b.
357377

358378
// MD-CIRCLE: # class Circle
359379
// MD-CIRCLE: *Defined at .{{[\/]}}include{{[\/]}}Circle.h#10*

0 commit comments

Comments
 (0)