Skip to content

Commit cc1c017

Browse files
committed
Mark static functions and members in normal processing
Visiting VarDecls looses context. Instead, track additional information about statics within the Info* classes, and update serialization to handle it. We can visit VarDecl's as a normal part of visiting Records, and keep the necessary context.
1 parent d0e1eaf commit cc1c017

File tree

9 files changed

+49
-82
lines changed

9 files changed

+49
-82
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
274274
return decodeRecord(R, I->Access, Blob);
275275
case FUNCTION_IS_METHOD:
276276
return decodeRecord(R, I->IsMethod, Blob);
277+
case FUNCTION_IS_STATIC:
278+
return decodeRecord(R, I->IsStatic, Blob);
277279
default:
278280
return llvm::createStringError(llvm::inconvertibleErrorCode(),
279281
"invalid field for FunctionInfo");
@@ -305,6 +307,8 @@ llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
305307
return decodeRecord(R, I->Name, Blob);
306308
case MEMBER_TYPE_ACCESS:
307309
return decodeRecord(R, I->Access, Blob);
310+
case MEMBER_TYPE_IS_STATIC:
311+
return decodeRecord(R, I->IsStatic, Blob);
308312
default:
309313
return llvm::createStringError(llvm::inconvertibleErrorCode(),
310314
"invalid field for MemberTypeInfo");

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
156156
{FIELD_DEFAULT_VALUE, {"DefaultValue", &StringAbbrev}},
157157
{MEMBER_TYPE_NAME, {"Name", &StringAbbrev}},
158158
{MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}},
159+
{MEMBER_TYPE_IS_STATIC, {"IsStatic", &BoolAbbrev}},
159160
{NAMESPACE_USR, {"USR", &SymbolIDAbbrev}},
160161
{NAMESPACE_NAME, {"Name", &StringAbbrev}},
161162
{NAMESPACE_PATH, {"Path", &StringAbbrev}},
@@ -187,6 +188,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
187188
{FUNCTION_LOCATION, {"Location", &LocationAbbrev}},
188189
{FUNCTION_ACCESS, {"Access", &IntAbbrev}},
189190
{FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}},
191+
{FUNCTION_IS_STATIC, {"IsStatic", &BoolAbbrev}},
190192
{REFERENCE_USR, {"USR", &SymbolIDAbbrev}},
191193
{REFERENCE_NAME, {"Name", &StringAbbrev}},
192194
{REFERENCE_QUAL_NAME, {"QualName", &StringAbbrev}},
@@ -222,7 +224,7 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
222224
// FieldType Block
223225
{BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_NAME, FIELD_DEFAULT_VALUE}},
224226
// MemberType Block
225-
{BI_MEMBER_TYPE_BLOCK_ID, {MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS}},
227+
{BI_MEMBER_TYPE_BLOCK_ID, {MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS, MEMBER_TYPE_IS_STATIC}},
226228
// Enum Block
227229
{BI_ENUM_BLOCK_ID,
228230
{ENUM_USR, ENUM_NAME, ENUM_DEFLOCATION, ENUM_LOCATION, ENUM_SCOPED}},
@@ -247,7 +249,7 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
247249
// Function Block
248250
{BI_FUNCTION_BLOCK_ID,
249251
{FUNCTION_USR, FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION,
250-
FUNCTION_ACCESS, FUNCTION_IS_METHOD}},
252+
FUNCTION_ACCESS, FUNCTION_IS_METHOD, FUNCTION_IS_STATIC}},
251253
// Reference Block
252254
{BI_REFERENCE_BLOCK_ID,
253255
{REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE,
@@ -465,6 +467,7 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) {
465467
emitBlock(T.Type, FieldId::F_type);
466468
emitRecord(T.Name, MEMBER_TYPE_NAME);
467469
emitRecord(T.Access, MEMBER_TYPE_ACCESS);
470+
emitRecord(T.IsStatic, MEMBER_TYPE_IS_STATIC);
468471
for (const auto &CI : T.Description)
469472
emitBlock(CI);
470473
}
@@ -600,6 +603,7 @@ void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
600603
emitBlock(CI);
601604
emitRecord(I.Access, FUNCTION_ACCESS);
602605
emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
606+
emitRecord(I.IsStatic, FUNCTION_IS_STATIC);
603607
if (I.DefLoc)
604608
emitRecord(*I.DefLoc, FUNCTION_DEFLOCATION);
605609
for (const auto &L : I.Loc)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enum RecordId {
8181
FUNCTION_LOCATION,
8282
FUNCTION_ACCESS,
8383
FUNCTION_IS_METHOD,
84+
FUNCTION_IS_STATIC,
8485
COMMENT_KIND,
8586
COMMENT_TEXT,
8687
COMMENT_NAME,
@@ -96,6 +97,7 @@ enum RecordId {
9697
FIELD_DEFAULT_VALUE,
9798
MEMBER_TYPE_NAME,
9899
MEMBER_TYPE_ACCESS,
100+
MEMBER_TYPE_IS_STATIC,
99101
NAMESPACE_USR,
100102
NAMESPACE_NAME,
101103
NAMESPACE_PATH,

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ genRecordMembersBlock(const llvm::SmallVector<MemberTypeInfo, 4> &Members,
419419
std::string Access = getAccessSpelling(M.Access).str();
420420
if (Access != "")
421421
Access = Access + " ";
422+
if(M.IsStatic)
423+
Access += "static ";
422424
auto LIBody = std::make_unique<TagNode>(HTMLTag::TAG_LI);
423425
auto MemberDecl = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
424426
MemberDecl->Children.emplace_back(std::make_unique<TextNode>(Access));
@@ -740,6 +742,12 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx,
740742
if (Access != "")
741743
FunctionHeader->Children.emplace_back(
742744
std::make_unique<TextNode>(Access + " "));
745+
if(I.IsStatic)
746+
FunctionHeader->Children.emplace_back(
747+
std::make_unique<TextNode>("static "));
748+
else{
749+
llvm::errs() << I.Name << " is not static\n";
750+
}
743751
if (I.ReturnType.Type.Name != "") {
744752
FunctionHeader->Children.emplace_back(
745753
genReference(I.ReturnType.Type, ParentInfoDir));

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ 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-
8985
bool MapASTVisitor::VisitEnumDecl(const EnumDecl *D) {
9086
return mapDecl(D, D->isThisDeclarationADefinition());
9187
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ 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);
4039
bool VisitEnumDecl(const EnumDecl *D);
4140
bool VisitCXXMethodDecl(const CXXMethodDecl *D);
4241
bool VisitFunctionDecl(const FunctionDecl *D);

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,9 @@ struct MemberTypeInfo : public FieldTypeInfo {
224224
: FieldTypeInfo(TI, Name), Access(Access) {}
225225

226226
bool operator==(const MemberTypeInfo &Other) const {
227-
return std::tie(Type, Name, Access, Description) ==
228-
std::tie(Other.Type, Other.Name, Other.Access, Other.Description);
227+
return std::tie(Type, Name, Access, IsStatic, Description) ==
228+
std::tie(Other.Type, Other.Name, Other.Access, Other.IsStatic,
229+
Other.Description);
229230
}
230231

231232
// Access level associated with this info (public, protected, private, none).
@@ -235,6 +236,7 @@ struct MemberTypeInfo : public FieldTypeInfo {
235236
AccessSpecifier Access = AccessSpecifier::AS_public;
236237

237238
std::vector<CommentInfo> Description; // Comment description of this field.
239+
bool IsStatic = false;
238240
};
239241

240242
struct Location {
@@ -314,6 +316,8 @@ struct NamespaceInfo : public Info {
314316

315317
// Info for symbols.
316318
struct SymbolInfo : public Info {
319+
bool IsStatic = false;
320+
317321
SymbolInfo(InfoType IT, SymbolID USR = SymbolID(),
318322
StringRef Name = StringRef(), StringRef Path = StringRef())
319323
: Info(IT, USR, Name, Path) {}

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

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static void
3030
populateParentNamespaces(llvm::SmallVector<Reference, 4> &Namespaces,
3131
const T *D, bool &IsAnonymousNamespace);
3232

33-
static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D);
33+
static void populateMemberTypeInfo(MemberTypeInfo &I, const Decl *D);
3434

3535
// A function to extract the appropriate relative path for a given info's
3636
// documentation. The path returned is a composite of the parent namespaces.
@@ -375,11 +375,11 @@ static AccessSpecifier getFinalAccessSpecifier(AccessSpecifier FirstAS,
375375
// record, the access specification of the field depends on the inheritance mode
376376
static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly,
377377
AccessSpecifier Access = AccessSpecifier::AS_public) {
378+
auto &LO = D->getLangOpts();
378379
for (const FieldDecl *F : D->fields()) {
379380
if (!shouldSerializeInfo(PublicOnly, /*IsInAnonymousNamespace=*/false, F))
380381
continue;
381382

382-
auto &LO = F->getLangOpts();
383383
// Use getAccessUnsafe so that we just get the default AS_none if it's not
384384
// valid, as opposed to an assert.
385385
MemberTypeInfo &NewMember = I.Members.emplace_back(
@@ -388,6 +388,19 @@ static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly,
388388
getFinalAccessSpecifier(Access, F->getAccessUnsafe()));
389389
populateMemberTypeInfo(NewMember, F);
390390
}
391+
const CXXRecordDecl *CPP = dyn_cast<CXXRecordDecl>(D);
392+
for (Decl *F : CPP->decls()) {
393+
if (auto *VD = dyn_cast<VarDecl>(F)) {
394+
if (VD->isStaticDataMember()) {
395+
MemberTypeInfo &NewMember = I.Members.emplace_back(
396+
getTypeInfoForType(VD->getTypeSourceInfo()->getType(), LO),
397+
VD->getNameAsString(),
398+
getFinalAccessSpecifier(Access, F->getAccessUnsafe()));
399+
NewMember.IsStatic = true;
400+
populateMemberTypeInfo(NewMember, VD);
401+
}
402+
}
403+
}
391404
}
392405

393406
static void parseEnumerators(EnumInfo &I, const EnumDecl *D) {
@@ -568,7 +581,7 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
568581
}
569582
}
570583

571-
static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D) {
584+
static void populateMemberTypeInfo(MemberTypeInfo &I, const Decl *D) {
572585
assert(D && "Expect non-null FieldDecl in populateMemberTypeInfo");
573586

574587
ASTContext& Context = D->getASTContext();
@@ -619,6 +632,7 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
619632
continue;
620633
FunctionInfo FI;
621634
FI.IsMethod = true;
635+
FI.IsStatic = MD->isStatic();
622636
// The seventh arg in populateFunctionInfo is a boolean passed by
623637
// reference, its value is not relevant in here so it's not used
624638
// anywhere besides the function call.
@@ -729,61 +743,6 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
729743
return {std::move(I), std::move(Parent)};
730744
}
731745

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-
}
787746

788747
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
789748
emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
@@ -811,6 +770,7 @@ emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
811770
return {};
812771

813772
Func.IsMethod = true;
773+
Func.IsStatic = D->isStatic();
814774

815775
const NamedDecl *Parent = nullptr;
816776
if (const auto *SD =

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,7 @@
5252
// JSON-INDEX-NEXT: "Name": "Calculator",
5353
// JSON-INDEX-NEXT: "RefType": "record",
5454
// JSON-INDEX-NEXT: "Path": "GlobalNamespace",
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: ]
55+
// JSON-INDEX-NEXT: "Children": []
6456
// JSON-INDEX-NEXT: },
6557
// JSON-INDEX-NEXT: {
6658
// JSON-INDEX-NEXT: "USR": "{{([0-9A-F]{40})}}",
@@ -142,9 +134,9 @@
142134
// HTML-CALC: <div>brief</div>
143135
// HTML-CALC: <p> Holds a public value.</p>
144136
// HTML-CALC: <div>public int public_val</div>
145-
146-
// HTML-CALC: <h2 id="Records">Records</h2>
147-
// HTML-CALC: <a href="../GlobalNamespace/Calculator/static_val.html">static_val</a>
137+
// HTML-CALC: <div>brief</div>
138+
// HTML-CALC: <p> A static value.</p>
139+
// HTML-CALC: <div>public static const int static_val</div>
148140

149141
// HTML-CALC: <h2 id="Functions">Functions</h2>
150142
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3>
@@ -202,7 +194,7 @@
202194
// HTML-CALC: <div>throw</div>
203195
// HTML-CALC: <p>if b is zero.</p>
204196

205-
// HTML-CALC: <p>public int mod(int a, int b)</p>
197+
// HTML-CALC: <p>public static int mod(int a, int b)</p>
206198
// CALC-NO-REPOSITORY: Defined at line 54 of file .{{.}}include{{.}}Calculator.h
207199
// CALC-REPOSITORY: Defined at line
208200
// CALC-REPOSITORY-NEXT: <a href="https://repository.com/./include/Calculator.h#54">54</a>
@@ -337,8 +329,6 @@
337329
// MD-CALC: Provides basic arithmetic operations.
338330
// MD-CALC: ## Members
339331
// MD-CALC: public int public_val
340-
// MD-CALC: ## Records
341-
// MD-CALC: static_val
342332
// MD-CALC: ## Functions
343333
// MD-CALC: ### add
344334
// MD-CALC: *public int add(int a, int b)*

0 commit comments

Comments
 (0)