brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.8 KiB · d88b0c9 Raw
341 lines · cpp
1//===-- clang-doc/BitcodeTest.cpp -----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "BitcodeReader.h"10#include "BitcodeWriter.h"11#include "ClangDocTest.h"12#include "Representation.h"13#include "llvm/Bitstream/BitstreamReader.h"14#include "llvm/Bitstream/BitstreamWriter.h"15#include "gtest/gtest.h"16 17namespace clang {18namespace doc {19 20template <typename T> static std::string writeInfo(T &I) {21  SmallString<2048> Buffer;22  llvm::BitstreamWriter Stream(Buffer);23  ClangDocBitcodeWriter Writer(Stream);24  Writer.emitBlock(I);25  return Buffer.str().str();26}27 28static std::string writeInfo(Info *I) {29  switch (I->IT) {30  case InfoType::IT_namespace:31    return writeInfo(*static_cast<NamespaceInfo *>(I));32  case InfoType::IT_record:33    return writeInfo(*static_cast<RecordInfo *>(I));34  case InfoType::IT_enum:35    return writeInfo(*static_cast<EnumInfo *>(I));36  case InfoType::IT_function:37    return writeInfo(*static_cast<FunctionInfo *>(I));38  case InfoType::IT_typedef:39    return writeInfo(*static_cast<TypedefInfo *>(I));40  case InfoType::IT_concept:41    return writeInfo(*static_cast<ConceptInfo *>(I));42  case InfoType::IT_variable:43    return writeInfo(*static_cast<VarInfo *>(I));44  case InfoType::IT_friend:45    return writeInfo(*static_cast<FriendInfo *>(I));46  case InfoType::IT_default:47    return "";48  }49}50 51static std::vector<std::unique_ptr<Info>> readInfo(StringRef Bitcode,52                                                   size_t NumInfos) {53  llvm::BitstreamCursor Stream(Bitcode);54  doc::ClangDocBitcodeReader Reader(Stream);55  auto Infos = Reader.readBitcode();56 57  // Check that there was no error in the read.58  assert(Infos);59  EXPECT_EQ(Infos.get().size(), NumInfos);60  return std::move(Infos.get());61}62 63TEST(BitcodeTest, emitNamespaceInfoBitcode) {64  NamespaceInfo I;65  I.Name = "r";66  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);67 68  I.Children.Namespaces.emplace_back(EmptySID, "ChildNamespace",69                                     InfoType::IT_namespace);70  I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);71  I.Children.Functions.emplace_back();72  I.Children.Enums.emplace_back();73 74  std::string WriteResult = writeInfo(&I);75  EXPECT_TRUE(WriteResult.size() > 0);76  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);77 78  CheckNamespaceInfo(&I, InfoAsNamespace(ReadResults[0].get()));79}80 81TEST(BitcodeTest, emitRecordInfoBitcode) {82  RecordInfo I;83  I.Name = "r";84  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);85 86  I.DefLoc = Location(10, 10, "test.cpp");87  I.Loc.emplace_back(12, 12, "test.cpp");88 89  I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);90  I.TagType = TagTypeKind::Class;91  I.IsTypeDef = true;92  I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,93                       AccessSpecifier::AS_public, true);94  I.Bases.back().Children.Functions.emplace_back();95  I.Bases.back().Members.emplace_back(TypeInfo("int"), "X",96                                      AccessSpecifier::AS_private);97  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);98  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);99 100  // Documentation for the data member.101  CommentInfo TopComment;102  TopComment.Kind = CommentKind::CK_FullComment;103  TopComment.Children.emplace_back(std::make_unique<CommentInfo>());104  CommentInfo *Brief = TopComment.Children.back().get();105  Brief->Kind = CommentKind::CK_ParagraphComment;106  Brief->Children.emplace_back(std::make_unique<CommentInfo>());107  Brief->Children.back()->Kind = CommentKind::CK_TextComment;108  Brief->Children.back()->Name = "ParagraphComment";109  Brief->Children.back()->Text = "Value of the thing.";110  I.Bases.back().Members.back().Description.emplace_back(std::move(TopComment));111 112  I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);113  I.Children.Functions.emplace_back();114  I.Children.Enums.emplace_back();115 116  std::string WriteResult = writeInfo(&I);117  EXPECT_TRUE(WriteResult.size() > 0);118  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);119 120  CheckRecordInfo(&I, InfoAsRecord(ReadResults[0].get()));121}122 123TEST(BitcodeTest, emitFunctionInfoBitcode) {124  FunctionInfo I;125  I.Name = "f";126  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);127 128  I.DefLoc = Location(10, 10, "test.cpp");129  I.Loc.emplace_back(12, 12, "test.cpp");130 131  I.ReturnType = TypeInfo("void");132  I.Params.emplace_back(TypeInfo("int"), "P");133 134  I.Access = AccessSpecifier::AS_none;135 136  std::string WriteResult = writeInfo(&I);137  EXPECT_TRUE(WriteResult.size() > 0);138  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);139 140  CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));141}142 143TEST(BitcodeTest, emitMethodInfoBitcode) {144  FunctionInfo I;145  I.Name = "f";146  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);147 148  I.DefLoc = Location(10, 10, "test.cpp");149  I.Loc.emplace_back(12, 12, "test.cpp");150 151  I.ReturnType = TypeInfo("void");152  I.Params.emplace_back(TypeInfo("int"), "P");153  I.IsMethod = true;154  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);155 156  I.Access = AccessSpecifier::AS_public;157 158  std::string WriteResult = writeInfo(&I);159  EXPECT_TRUE(WriteResult.size() > 0);160  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);161 162  CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));163}164 165TEST(BitcodeTest, emitEnumInfoBitcode) {166  EnumInfo I;167  I.Name = "e";168  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);169 170  I.DefLoc = Location(10, 10, "test.cpp");171  I.Loc.emplace_back(12, 12, "test.cpp");172 173  I.Members.emplace_back("X");174  I.Scoped = true;175 176  std::string WriteResult = writeInfo(&I);177  EXPECT_TRUE(WriteResult.size() > 0);178  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);179 180  CheckEnumInfo(&I, InfoAsEnum(ReadResults[0].get()));181}182 183TEST(BitcodeTest, emitTypedefInfoBitcode) {184  TypedefInfo I;185  I.Name = "MyInt";186  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);187 188  I.DefLoc = Location(10, 10, "test.cpp");189  I.Underlying = TypeInfo("unsigned");190  I.IsUsing = true;191 192  CommentInfo Top;193  Top.Kind = CommentKind::CK_FullComment;194 195  Top.Children.emplace_back(std::make_unique<CommentInfo>());196  CommentInfo *BlankLine = Top.Children.back().get();197  BlankLine->Kind = CommentKind::CK_ParagraphComment;198  BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());199  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;200 201  I.Description.emplace_back(std::move(Top));202 203  std::string WriteResult = writeInfo(&I);204  EXPECT_TRUE(WriteResult.size() > 0);205  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);206 207  CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0].get()));208 209  // Check one with no IsUsing set, no description, and no definition location.210  TypedefInfo I2;211  I2.Name = "SomethingElse";212  I2.IsUsing = false;213  I2.Underlying = TypeInfo("int");214 215  WriteResult = writeInfo(&I2);216  EXPECT_TRUE(WriteResult.size() > 0);217  ReadResults = readInfo(WriteResult, 1);218  CheckTypedefInfo(&I2, InfoAsTypedef(ReadResults[0].get()));219}220 221TEST(SerializeTest, emitInfoWithCommentBitcode) {222  FunctionInfo F;223  F.Name = "F";224  F.ReturnType = TypeInfo("void");225  F.DefLoc = Location(0, 0, "test.cpp");226  F.Params.emplace_back(TypeInfo("int"), "I");227 228  CommentInfo Top;229  Top.Kind = CommentKind::CK_FullComment;230 231  Top.Children.emplace_back(std::make_unique<CommentInfo>());232  CommentInfo *BlankLine = Top.Children.back().get();233  BlankLine->Kind = CommentKind::CK_ParagraphComment;234  BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());235  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;236 237  Top.Children.emplace_back(std::make_unique<CommentInfo>());238  CommentInfo *Brief = Top.Children.back().get();239  Brief->Kind = CommentKind::CK_ParagraphComment;240  Brief->Children.emplace_back(std::make_unique<CommentInfo>());241  Brief->Children.back()->Kind = CommentKind::CK_TextComment;242  Brief->Children.back()->Name = "ParagraphComment";243  Brief->Children.back()->Text = " Brief description.";244 245  Top.Children.emplace_back(std::make_unique<CommentInfo>());246  CommentInfo *Extended = Top.Children.back().get();247  Extended->Kind = CommentKind::CK_ParagraphComment;248  Extended->Children.emplace_back(std::make_unique<CommentInfo>());249  Extended->Children.back()->Kind = CommentKind::CK_TextComment;250  Extended->Children.back()->Text = " Extended description that";251  Extended->Children.emplace_back(std::make_unique<CommentInfo>());252  Extended->Children.back()->Kind = CommentKind::CK_TextComment;253  Extended->Children.back()->Text = " continues onto the next line.";254 255  Top.Children.emplace_back(std::make_unique<CommentInfo>());256  CommentInfo *HTML = Top.Children.back().get();257  HTML->Kind = CommentKind::CK_ParagraphComment;258  HTML->Children.emplace_back(std::make_unique<CommentInfo>());259  HTML->Children.back()->Kind = CommentKind::CK_TextComment;260  HTML->Children.emplace_back(std::make_unique<CommentInfo>());261  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;262  HTML->Children.back()->Name = "ul";263  HTML->Children.back()->AttrKeys.emplace_back("class");264  HTML->Children.back()->AttrValues.emplace_back("test");265  HTML->Children.emplace_back(std::make_unique<CommentInfo>());266  HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;267  HTML->Children.back()->Name = "li";268  HTML->Children.emplace_back(std::make_unique<CommentInfo>());269  HTML->Children.back()->Kind = CommentKind::CK_TextComment;270  HTML->Children.back()->Text = " Testing.";271  HTML->Children.emplace_back(std::make_unique<CommentInfo>());272  HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;273  HTML->Children.back()->Name = "ul";274  HTML->Children.back()->SelfClosing = true;275 276  Top.Children.emplace_back(std::make_unique<CommentInfo>());277  CommentInfo *Verbatim = Top.Children.back().get();278  Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;279  Verbatim->Name = "verbatim";280  Verbatim->CloseName = "endverbatim";281  Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());282  Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;283  Verbatim->Children.back()->Text = " The description continues.";284 285  Top.Children.emplace_back(std::make_unique<CommentInfo>());286  CommentInfo *ParamOut = Top.Children.back().get();287  ParamOut->Kind = CommentKind::CK_ParamCommandComment;288  ParamOut->Direction = "[out]";289  ParamOut->ParamName = "I";290  ParamOut->Explicit = true;291  ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());292  ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;293  ParamOut->Children.back()->Children.emplace_back(294      std::make_unique<CommentInfo>());295  ParamOut->Children.back()->Children.back()->Kind =296      CommentKind::CK_TextComment;297  ParamOut->Children.back()->Children.emplace_back(298      std::make_unique<CommentInfo>());299  ParamOut->Children.back()->Children.back()->Kind =300      CommentKind::CK_TextComment;301  ParamOut->Children.back()->Children.back()->Text = " is a parameter.";302 303  Top.Children.emplace_back(std::make_unique<CommentInfo>());304  CommentInfo *ParamIn = Top.Children.back().get();305  ParamIn->Kind = CommentKind::CK_ParamCommandComment;306  ParamIn->Direction = "[in]";307  ParamIn->ParamName = "J";308  ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());309  ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;310  ParamIn->Children.back()->Children.emplace_back(311      std::make_unique<CommentInfo>());312  ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;313  ParamIn->Children.back()->Children.back()->Text = " is a parameter.";314  ParamIn->Children.back()->Children.emplace_back(315      std::make_unique<CommentInfo>());316  ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;317 318  Top.Children.emplace_back(std::make_unique<CommentInfo>());319  CommentInfo *Return = Top.Children.back().get();320  Return->Kind = CommentKind::CK_BlockCommandComment;321  Return->Name = "return";322  Return->Explicit = true;323  Return->Children.emplace_back(std::make_unique<CommentInfo>());324  Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;325  Return->Children.back()->Children.emplace_back(326      std::make_unique<CommentInfo>());327  Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;328  Return->Children.back()->Children.back()->Text = "void";329 330  F.Description.emplace_back(std::move(Top));331 332  std::string WriteResult = writeInfo(&F);333  EXPECT_TRUE(WriteResult.size() > 0);334  std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);335 336  CheckFunctionInfo(&F, InfoAsFunction(ReadResults[0].get()));337}338 339} // namespace doc340} // namespace clang341