[clang-tidy][modernize-use-starts-ends-with] Fix operator rewriting false negative...
[llvm-project.git] / clang-tools-extra / unittests / clang-doc / BitcodeTest.cpp
blob5b9745af7810a9a917e25174096d036945ba145d
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-exception
6 //
7 //===----------------------------------------------------------------------===//
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"
17 namespace clang {
18 namespace doc {
20 template <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();
28 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 default:
41 return "";
45 std::vector<std::unique_ptr<Info>> readInfo(StringRef Bitcode,
46 size_t NumInfos) {
47 llvm::BitstreamCursor Stream(Bitcode);
48 doc::ClangDocBitcodeReader Reader(Stream);
49 auto Infos = Reader.readBitcode();
51 // Check that there was no error in the read.
52 assert(Infos);
53 EXPECT_EQ(Infos.get().size(), NumInfos);
54 return std::move(Infos.get());
57 TEST(BitcodeTest, emitNamespaceInfoBitcode) {
58 NamespaceInfo I;
59 I.Name = "r";
60 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
62 I.Children.Namespaces.emplace_back(EmptySID, "ChildNamespace",
63 InfoType::IT_namespace);
64 I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
65 I.Children.Functions.emplace_back();
66 I.Children.Enums.emplace_back();
68 std::string WriteResult = writeInfo(&I);
69 EXPECT_TRUE(WriteResult.size() > 0);
70 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
72 CheckNamespaceInfo(&I, InfoAsNamespace(ReadResults[0].get()));
75 TEST(BitcodeTest, emitRecordInfoBitcode) {
76 RecordInfo I;
77 I.Name = "r";
78 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
80 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
81 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
83 I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
84 I.TagType = TagTypeKind::Class;
85 I.IsTypeDef = true;
86 I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
87 AccessSpecifier::AS_public, true);
88 I.Bases.back().Children.Functions.emplace_back();
89 I.Bases.back().Members.emplace_back(TypeInfo("int"), "X",
90 AccessSpecifier::AS_private);
91 I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
92 I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
94 // Documentation for the data member.
95 CommentInfo TopComment;
96 TopComment.Kind = "FullComment";
97 TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
98 CommentInfo *Brief = TopComment.Children.back().get();
99 Brief->Kind = "ParagraphComment";
100 Brief->Children.emplace_back(std::make_unique<CommentInfo>());
101 Brief->Children.back()->Kind = "TextComment";
102 Brief->Children.back()->Name = "ParagraphComment";
103 Brief->Children.back()->Text = "Value of the thing.";
104 I.Bases.back().Members.back().Description.emplace_back(std::move(TopComment));
106 I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
107 I.Children.Functions.emplace_back();
108 I.Children.Enums.emplace_back();
110 std::string WriteResult = writeInfo(&I);
111 EXPECT_TRUE(WriteResult.size() > 0);
112 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
114 CheckRecordInfo(&I, InfoAsRecord(ReadResults[0].get()));
117 TEST(BitcodeTest, emitFunctionInfoBitcode) {
118 FunctionInfo I;
119 I.Name = "f";
120 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
122 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
123 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
125 I.ReturnType = TypeInfo("void");
126 I.Params.emplace_back(TypeInfo("int"), "P");
128 I.Access = AccessSpecifier::AS_none;
130 std::string WriteResult = writeInfo(&I);
131 EXPECT_TRUE(WriteResult.size() > 0);
132 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
134 CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));
137 TEST(BitcodeTest, emitMethodInfoBitcode) {
138 FunctionInfo I;
139 I.Name = "f";
140 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
142 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
143 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
145 I.ReturnType = TypeInfo("void");
146 I.Params.emplace_back(TypeInfo("int"), "P");
147 I.IsMethod = true;
148 I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
150 I.Access = AccessSpecifier::AS_public;
152 std::string WriteResult = writeInfo(&I);
153 EXPECT_TRUE(WriteResult.size() > 0);
154 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
156 CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));
159 TEST(BitcodeTest, emitEnumInfoBitcode) {
160 EnumInfo I;
161 I.Name = "e";
162 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
164 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
165 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
167 I.Members.emplace_back("X");
168 I.Scoped = true;
170 std::string WriteResult = writeInfo(&I);
171 EXPECT_TRUE(WriteResult.size() > 0);
172 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
174 CheckEnumInfo(&I, InfoAsEnum(ReadResults[0].get()));
177 TEST(BitcodeTest, emitTypedefInfoBitcode) {
178 TypedefInfo I;
179 I.Name = "MyInt";
180 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
182 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
183 I.Underlying = TypeInfo("unsigned");
184 I.IsUsing = true;
186 CommentInfo Top;
187 Top.Kind = "FullComment";
189 Top.Children.emplace_back(std::make_unique<CommentInfo>());
190 CommentInfo *BlankLine = Top.Children.back().get();
191 BlankLine->Kind = "ParagraphComment";
192 BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
193 BlankLine->Children.back()->Kind = "TextComment";
195 I.Description.emplace_back(std::move(Top));
197 std::string WriteResult = writeInfo(&I);
198 EXPECT_TRUE(WriteResult.size() > 0);
199 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
201 CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0].get()));
203 // Check one with no IsUsing set, no description, and no definition location.
204 TypedefInfo I2;
205 I2.Name = "SomethingElse";
206 I2.IsUsing = false;
207 I2.Underlying = TypeInfo("int");
209 WriteResult = writeInfo(&I2);
210 EXPECT_TRUE(WriteResult.size() > 0);
211 ReadResults = readInfo(WriteResult, 1);
212 CheckTypedefInfo(&I2, InfoAsTypedef(ReadResults[0].get()));
215 TEST(SerializeTest, emitInfoWithCommentBitcode) {
216 FunctionInfo F;
217 F.Name = "F";
218 F.ReturnType = TypeInfo("void");
219 F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
220 F.Params.emplace_back(TypeInfo("int"), "I");
222 CommentInfo Top;
223 Top.Kind = "FullComment";
225 Top.Children.emplace_back(std::make_unique<CommentInfo>());
226 CommentInfo *BlankLine = Top.Children.back().get();
227 BlankLine->Kind = "ParagraphComment";
228 BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
229 BlankLine->Children.back()->Kind = "TextComment";
231 Top.Children.emplace_back(std::make_unique<CommentInfo>());
232 CommentInfo *Brief = Top.Children.back().get();
233 Brief->Kind = "ParagraphComment";
234 Brief->Children.emplace_back(std::make_unique<CommentInfo>());
235 Brief->Children.back()->Kind = "TextComment";
236 Brief->Children.back()->Name = "ParagraphComment";
237 Brief->Children.back()->Text = " Brief description.";
239 Top.Children.emplace_back(std::make_unique<CommentInfo>());
240 CommentInfo *Extended = Top.Children.back().get();
241 Extended->Kind = "ParagraphComment";
242 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
243 Extended->Children.back()->Kind = "TextComment";
244 Extended->Children.back()->Text = " Extended description that";
245 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
246 Extended->Children.back()->Kind = "TextComment";
247 Extended->Children.back()->Text = " continues onto the next line.";
249 Top.Children.emplace_back(std::make_unique<CommentInfo>());
250 CommentInfo *HTML = Top.Children.back().get();
251 HTML->Kind = "ParagraphComment";
252 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
253 HTML->Children.back()->Kind = "TextComment";
254 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
255 HTML->Children.back()->Kind = "HTMLStartTagComment";
256 HTML->Children.back()->Name = "ul";
257 HTML->Children.back()->AttrKeys.emplace_back("class");
258 HTML->Children.back()->AttrValues.emplace_back("test");
259 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
260 HTML->Children.back()->Kind = "HTMLStartTagComment";
261 HTML->Children.back()->Name = "li";
262 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
263 HTML->Children.back()->Kind = "TextComment";
264 HTML->Children.back()->Text = " Testing.";
265 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
266 HTML->Children.back()->Kind = "HTMLEndTagComment";
267 HTML->Children.back()->Name = "ul";
268 HTML->Children.back()->SelfClosing = true;
270 Top.Children.emplace_back(std::make_unique<CommentInfo>());
271 CommentInfo *Verbatim = Top.Children.back().get();
272 Verbatim->Kind = "VerbatimBlockComment";
273 Verbatim->Name = "verbatim";
274 Verbatim->CloseName = "endverbatim";
275 Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
276 Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
277 Verbatim->Children.back()->Text = " The description continues.";
279 Top.Children.emplace_back(std::make_unique<CommentInfo>());
280 CommentInfo *ParamOut = Top.Children.back().get();
281 ParamOut->Kind = "ParamCommandComment";
282 ParamOut->Direction = "[out]";
283 ParamOut->ParamName = "I";
284 ParamOut->Explicit = true;
285 ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
286 ParamOut->Children.back()->Kind = "ParagraphComment";
287 ParamOut->Children.back()->Children.emplace_back(
288 std::make_unique<CommentInfo>());
289 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
290 ParamOut->Children.back()->Children.emplace_back(
291 std::make_unique<CommentInfo>());
292 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
293 ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
295 Top.Children.emplace_back(std::make_unique<CommentInfo>());
296 CommentInfo *ParamIn = Top.Children.back().get();
297 ParamIn->Kind = "ParamCommandComment";
298 ParamIn->Direction = "[in]";
299 ParamIn->ParamName = "J";
300 ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
301 ParamIn->Children.back()->Kind = "ParagraphComment";
302 ParamIn->Children.back()->Children.emplace_back(
303 std::make_unique<CommentInfo>());
304 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
305 ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
306 ParamIn->Children.back()->Children.emplace_back(
307 std::make_unique<CommentInfo>());
308 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
310 Top.Children.emplace_back(std::make_unique<CommentInfo>());
311 CommentInfo *Return = Top.Children.back().get();
312 Return->Kind = "BlockCommandComment";
313 Return->Name = "return";
314 Return->Explicit = true;
315 Return->Children.emplace_back(std::make_unique<CommentInfo>());
316 Return->Children.back()->Kind = "ParagraphComment";
317 Return->Children.back()->Children.emplace_back(
318 std::make_unique<CommentInfo>());
319 Return->Children.back()->Children.back()->Kind = "TextComment";
320 Return->Children.back()->Children.back()->Text = "void";
322 F.Description.emplace_back(std::move(Top));
324 std::string WriteResult = writeInfo(&F);
325 EXPECT_TRUE(WriteResult.size() > 0);
326 std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
328 CheckFunctionInfo(&F, InfoAsFunction(ReadResults[0].get()));
331 } // namespace doc
332 } // namespace clang