[clang-doc] Fix typedef/using output.

Provides an initializer for the TypedefInfo.IsUsing member. Previously
this member was uninitialized and would produce random output.

Adds the Description (code comments) to the bitcode reader/writer.
Previously the typedef/using descriptions were lost during the bitcode
round-trip. Adds a test for this.

Differential Revision: https://reviews.llvm.org/D136638
This commit is contained in:
Brett Wilson 2022-10-24 13:48:55 -07:00
parent 39917b5e01
commit 7231c9966e
4 changed files with 34 additions and 11 deletions

View File

@ -368,28 +368,27 @@ template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
I->Description.emplace_back(); return &I->Description.emplace_back();
return &I->Description.back();
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
I->Description.emplace_back(); return &I->Description.emplace_back();
return &I->Description.back();
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
I->Description.emplace_back(); return &I->Description.emplace_back();
return &I->Description.back();
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
I->Description.emplace_back(); return &I->Description.emplace_back();
return &I->Description.back();
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
I->Description.emplace_back(); return &I->Description.emplace_back();
return &I->Description.back(); }
template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
return &I->Description.emplace_back();
} }
template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) { template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {

View File

@ -432,6 +432,8 @@ void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) {
emitRecord(T.Name, TYPEDEF_NAME); emitRecord(T.Name, TYPEDEF_NAME);
for (const auto &N : T.Namespace) for (const auto &N : T.Namespace)
emitBlock(N, FieldId::F_namespace); emitBlock(N, FieldId::F_namespace);
for (const auto &CI : T.Description)
emitBlock(CI);
if (T.DefLoc) if (T.DefLoc)
emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION); emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION);
emitRecord(T.IsUsing, TYPEDEF_IS_USING); emitRecord(T.IsUsing, TYPEDEF_IS_USING);

View File

@ -365,7 +365,7 @@ struct TypedefInfo : public SymbolInfo {
// using MyVector = std::vector<int> // using MyVector = std::vector<int>
// False means it's a C-style typedef: // False means it's a C-style typedef:
// typedef std::vector<int> MyVector; // typedef std::vector<int> MyVector;
bool IsUsing; bool IsUsing = false;
}; };
struct BaseRecordInfo : public RecordInfo { struct BaseRecordInfo : public RecordInfo {

View File

@ -183,11 +183,33 @@ TEST(BitcodeTest, emitTypedefInfoBitcode) {
I.Underlying = TypeInfo("unsigned"); I.Underlying = TypeInfo("unsigned");
I.IsUsing = true; I.IsUsing = true;
CommentInfo Top;
Top.Kind = "FullComment";
Top.Children.emplace_back(std::make_unique<CommentInfo>());
CommentInfo *BlankLine = Top.Children.back().get();
BlankLine->Kind = "ParagraphComment";
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
BlankLine->Children.back()->Kind = "TextComment";
I.Description.emplace_back(std::move(Top));
std::string WriteResult = writeInfo(&I); std::string WriteResult = writeInfo(&I);
EXPECT_TRUE(WriteResult.size() > 0); EXPECT_TRUE(WriteResult.size() > 0);
std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1); std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0].get())); CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0].get()));
// Check one with no IsUsing set, no description, and no definition location.
TypedefInfo I2;
I2.Name = "SomethingElse";
I2.IsUsing = false;
I2.Underlying = TypeInfo("int");
WriteResult = writeInfo(&I2);
EXPECT_TRUE(WriteResult.size() > 0);
ReadResults = readInfo(WriteResult, 1);
CheckTypedefInfo(&I2, InfoAsTypedef(ReadResults[0].get()));
} }
TEST(SerializeTest, emitInfoWithCommentBitcode) { TEST(SerializeTest, emitInfoWithCommentBitcode) {