168049b1aSJulie Hockett //===-- clang-doc/SerializeTest.cpp ---------------------------------------===// 268049b1aSJulie Hockett // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 668049b1aSJulie Hockett // 768049b1aSJulie Hockett //===----------------------------------------------------------------------===// 868049b1aSJulie Hockett 968049b1aSJulie Hockett #include "Serialize.h" 1068049b1aSJulie Hockett #include "ClangDocTest.h" 1168049b1aSJulie Hockett #include "Representation.h" 1268049b1aSJulie Hockett #include "clang/AST/Comment.h" 1368049b1aSJulie Hockett #include "clang/AST/RecursiveASTVisitor.h" 1468049b1aSJulie Hockett #include "gtest/gtest.h" 1568049b1aSJulie Hockett 1668049b1aSJulie Hockett namespace clang { 1768049b1aSJulie Hockett namespace doc { 1868049b1aSJulie Hockett 1968049b1aSJulie Hockett class ClangDocSerializeTestVisitor 2068049b1aSJulie Hockett : public RecursiveASTVisitor<ClangDocSerializeTestVisitor> { 2168049b1aSJulie Hockett 2268049b1aSJulie Hockett EmittedInfoList &EmittedInfos; 2368049b1aSJulie Hockett bool Public; 2468049b1aSJulie Hockett 2568049b1aSJulie Hockett comments::FullComment *getComment(const NamedDecl *D) const { 2668049b1aSJulie Hockett if (RawComment *Comment = 2768049b1aSJulie Hockett D->getASTContext().getRawCommentForDeclNoCache(D)) { 2868049b1aSJulie Hockett Comment->setAttached(); 2968049b1aSJulie Hockett return Comment->parse(D->getASTContext(), nullptr, D); 3068049b1aSJulie Hockett } 3168049b1aSJulie Hockett return nullptr; 3268049b1aSJulie Hockett } 3368049b1aSJulie Hockett 3468049b1aSJulie Hockett public: 3568049b1aSJulie Hockett ClangDocSerializeTestVisitor(EmittedInfoList &EmittedInfos, bool Public) 3668049b1aSJulie Hockett : EmittedInfos(EmittedInfos), Public(Public) {} 3768049b1aSJulie Hockett 38097aedc9SJulie Hockett template <typename T> bool mapDecl(const T *D) { 3968049b1aSJulie Hockett auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, 40665e9676SDiego Astiazaran /*File=*/"test.cpp", true, Public); 41097aedc9SJulie Hockett if (I.first) 42097aedc9SJulie Hockett EmittedInfos.emplace_back(std::move(I.first)); 43097aedc9SJulie Hockett if (I.second) 44097aedc9SJulie Hockett EmittedInfos.emplace_back(std::move(I.second)); 4568049b1aSJulie Hockett return true; 4668049b1aSJulie Hockett } 4768049b1aSJulie Hockett 48097aedc9SJulie Hockett bool VisitNamespaceDecl(const NamespaceDecl *D) { return mapDecl(D); } 49097aedc9SJulie Hockett 5068049b1aSJulie Hockett bool VisitFunctionDecl(const FunctionDecl *D) { 5168049b1aSJulie Hockett // Don't visit CXXMethodDecls twice 5268049b1aSJulie Hockett if (dyn_cast<CXXMethodDecl>(D)) 5368049b1aSJulie Hockett return true; 54097aedc9SJulie Hockett return mapDecl(D); 5568049b1aSJulie Hockett } 5668049b1aSJulie Hockett 57097aedc9SJulie Hockett bool VisitCXXMethodDecl(const CXXMethodDecl *D) { return mapDecl(D); } 5868049b1aSJulie Hockett 59097aedc9SJulie Hockett bool VisitRecordDecl(const RecordDecl *D) { return mapDecl(D); } 6068049b1aSJulie Hockett 61097aedc9SJulie Hockett bool VisitEnumDecl(const EnumDecl *D) { return mapDecl(D); } 6221fb70c6SBrett Wilson 6321fb70c6SBrett Wilson bool VisitTypedefDecl(const TypedefDecl *D) { return mapDecl(D); } 6421fb70c6SBrett Wilson 6521fb70c6SBrett Wilson bool VisitTypeAliasDecl(const TypeAliasDecl *D) { return mapDecl(D); } 6668049b1aSJulie Hockett }; 6768049b1aSJulie Hockett 6868049b1aSJulie Hockett void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool Public, 6968049b1aSJulie Hockett EmittedInfoList &EmittedInfos) { 7068049b1aSJulie Hockett auto ASTUnit = clang::tooling::buildASTFromCode(Code); 7168049b1aSJulie Hockett auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); 7268049b1aSJulie Hockett ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); 7368049b1aSJulie Hockett Visitor.TraverseTranslationUnitDecl(TU); 7468049b1aSJulie Hockett ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); 7568049b1aSJulie Hockett } 7668049b1aSJulie Hockett 7768049b1aSJulie Hockett void ExtractInfosFromCodeWithArgs(StringRef Code, size_t NumExpectedInfos, 7868049b1aSJulie Hockett bool Public, EmittedInfoList &EmittedInfos, 7968049b1aSJulie Hockett std::vector<std::string> &Args) { 8068049b1aSJulie Hockett auto ASTUnit = clang::tooling::buildASTFromCodeWithArgs(Code, Args); 8168049b1aSJulie Hockett auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); 8268049b1aSJulie Hockett ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); 8368049b1aSJulie Hockett Visitor.TraverseTranslationUnitDecl(TU); 8468049b1aSJulie Hockett ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); 8568049b1aSJulie Hockett } 8668049b1aSJulie Hockett 8799baa10fSBrett Wilson // Constructs a comment definition as the parser would for one comment line. 8899baa10fSBrett Wilson /* TODO uncomment this when the missing comment is fixed in emitRecordInfo and 8999baa10fSBrett Wilson the code that calls this is re-enabled. 9099baa10fSBrett Wilson CommentInfo MakeOneLineCommentInfo(const std::string &Text) { 9199baa10fSBrett Wilson CommentInfo TopComment; 9299baa10fSBrett Wilson TopComment.Kind = "FullComment"; 9399baa10fSBrett Wilson TopComment.Children.emplace_back(std::make_unique<CommentInfo>()); 9499baa10fSBrett Wilson 9599baa10fSBrett Wilson CommentInfo *Brief = TopComment.Children.back().get(); 9699baa10fSBrett Wilson Brief->Kind = "ParagraphComment"; 9799baa10fSBrett Wilson 9899baa10fSBrett Wilson Brief->Children.emplace_back(std::make_unique<CommentInfo>()); 9999baa10fSBrett Wilson Brief->Children.back()->Kind = "TextComment"; 10099baa10fSBrett Wilson Brief->Children.back()->Name = "ParagraphComment"; 10199baa10fSBrett Wilson Brief->Children.back()->Text = Text; 10299baa10fSBrett Wilson 10399baa10fSBrett Wilson return TopComment; 10499baa10fSBrett Wilson } 10599baa10fSBrett Wilson */ 10699baa10fSBrett Wilson 10768049b1aSJulie Hockett // Test serialization of namespace declarations. 10868049b1aSJulie Hockett TEST(SerializeTest, emitNamespaceInfo) { 10968049b1aSJulie Hockett EmittedInfoList Infos; 110097aedc9SJulie Hockett ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 5, 11168049b1aSJulie Hockett /*Public=*/false, Infos); 11268049b1aSJulie Hockett 11368049b1aSJulie Hockett NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); 11468049b1aSJulie Hockett NamespaceInfo ExpectedA(EmptySID, "A"); 11568049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedA, A); 11668049b1aSJulie Hockett 117097aedc9SJulie Hockett NamespaceInfo *B = InfoAsNamespace(Infos[2].get()); 1186169a730SDiego Astiazaran NamespaceInfo ExpectedB(EmptySID, /*Name=*/"B", /*Path=*/"A"); 11968049b1aSJulie Hockett ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); 12068049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedB, B); 12168049b1aSJulie Hockett 122097aedc9SJulie Hockett NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[4].get()); 12368049b1aSJulie Hockett NamespaceInfo ExpectedBWithFunction(EmptySID); 12468049b1aSJulie Hockett FunctionInfo F; 12568049b1aSJulie Hockett F.Name = "f"; 1260afc6085SBrett Wilson F.ReturnType = TypeInfo("void"); 12768049b1aSJulie Hockett F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 12868049b1aSJulie Hockett F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace); 12968049b1aSJulie Hockett F.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); 1306a29ae4bSDiego Astiazaran F.Access = AccessSpecifier::AS_none; 13121fb70c6SBrett Wilson ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F)); 13268049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); 13368049b1aSJulie Hockett } 13468049b1aSJulie Hockett 13568049b1aSJulie Hockett TEST(SerializeTest, emitAnonymousNamespaceInfo) { 13668049b1aSJulie Hockett EmittedInfoList Infos; 137097aedc9SJulie Hockett ExtractInfosFromCode("namespace { }", 2, /*Public=*/false, Infos); 13868049b1aSJulie Hockett 13968049b1aSJulie Hockett NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); 14068049b1aSJulie Hockett NamespaceInfo ExpectedA(EmptySID); 141d900ef0aSJulie Hockett ExpectedA.Name = "@nonymous_namespace"; 14268049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedA, A); 14368049b1aSJulie Hockett } 14468049b1aSJulie Hockett 14568049b1aSJulie Hockett // Test serialization of record declarations. 14668049b1aSJulie Hockett TEST(SerializeTest, emitRecordInfo) { 14768049b1aSJulie Hockett EmittedInfoList Infos; 14868049b1aSJulie Hockett ExtractInfosFromCode(R"raw(class E { 14968049b1aSJulie Hockett public: 15068049b1aSJulie Hockett E() {} 15199baa10fSBrett Wilson 15299baa10fSBrett Wilson // Some docs. 15399baa10fSBrett Wilson int value; 15468049b1aSJulie Hockett protected: 15568049b1aSJulie Hockett void ProtectedMethod(); 156b1f01e27SJulie Hockett }; 157b1f01e27SJulie Hockett template <typename T> 158b1f01e27SJulie Hockett struct F { 159b1f01e27SJulie Hockett void TemplateMethod(); 160b1f01e27SJulie Hockett }; 161b1f01e27SJulie Hockett template <> 162b1f01e27SJulie Hockett void F<int>::TemplateMethod(); 163b1f01e27SJulie Hockett typedef struct {} G;)raw", 164097aedc9SJulie Hockett 10, /*Public=*/false, Infos); 16568049b1aSJulie Hockett 16668049b1aSJulie Hockett RecordInfo *E = InfoAsRecord(Infos[0].get()); 167b46131e5SDiego Astiazaran RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace"); 168b46131e5SDiego Astiazaran ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace", 169b46131e5SDiego Astiazaran InfoType::IT_namespace); 170edd690b0SVlad Serebrennikov ExpectedE.TagType = TagTypeKind::Class; 17168049b1aSJulie Hockett ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 1720afc6085SBrett Wilson ExpectedE.Members.emplace_back(TypeInfo("int"), "value", 1730afc6085SBrett Wilson AccessSpecifier::AS_public); 17499baa10fSBrett Wilson // TODO the data member should have the docstring on it: 17599baa10fSBrett Wilson //ExpectedE.Members.back().Description.push_back(MakeOneLineCommentInfo(" Some docs")); 17668049b1aSJulie Hockett CheckRecordInfo(&ExpectedE, E); 17768049b1aSJulie Hockett 178097aedc9SJulie Hockett RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[2].get()); 17968049b1aSJulie Hockett RecordInfo ExpectedRecordWithEConstructor(EmptySID); 18068049b1aSJulie Hockett FunctionInfo EConstructor; 18168049b1aSJulie Hockett EConstructor.Name = "E"; 18268049b1aSJulie Hockett EConstructor.Parent = Reference(EmptySID, "E", InfoType::IT_record); 1830afc6085SBrett Wilson EConstructor.ReturnType = TypeInfo("void"); 18468049b1aSJulie Hockett EConstructor.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 18568049b1aSJulie Hockett EConstructor.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); 186b46131e5SDiego Astiazaran EConstructor.Namespace.emplace_back(EmptySID, "GlobalNamespace", 187b46131e5SDiego Astiazaran InfoType::IT_namespace); 18868049b1aSJulie Hockett EConstructor.Access = AccessSpecifier::AS_public; 18968049b1aSJulie Hockett EConstructor.IsMethod = true; 19021fb70c6SBrett Wilson ExpectedRecordWithEConstructor.Children.Functions.emplace_back( 19168049b1aSJulie Hockett std::move(EConstructor)); 19268049b1aSJulie Hockett CheckRecordInfo(&ExpectedRecordWithEConstructor, RecordWithEConstructor); 19368049b1aSJulie Hockett 194097aedc9SJulie Hockett RecordInfo *RecordWithMethod = InfoAsRecord(Infos[3].get()); 19568049b1aSJulie Hockett RecordInfo ExpectedRecordWithMethod(EmptySID); 19668049b1aSJulie Hockett FunctionInfo Method; 19768049b1aSJulie Hockett Method.Name = "ProtectedMethod"; 19868049b1aSJulie Hockett Method.Parent = Reference(EmptySID, "E", InfoType::IT_record); 1990afc6085SBrett Wilson Method.ReturnType = TypeInfo("void"); 20068049b1aSJulie Hockett Method.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); 20168049b1aSJulie Hockett Method.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); 202b46131e5SDiego Astiazaran Method.Namespace.emplace_back(EmptySID, "GlobalNamespace", 203b46131e5SDiego Astiazaran InfoType::IT_namespace); 20468049b1aSJulie Hockett Method.Access = AccessSpecifier::AS_protected; 20568049b1aSJulie Hockett Method.IsMethod = true; 20621fb70c6SBrett Wilson ExpectedRecordWithMethod.Children.Functions.emplace_back(std::move(Method)); 20768049b1aSJulie Hockett CheckRecordInfo(&ExpectedRecordWithMethod, RecordWithMethod); 208b1f01e27SJulie Hockett 209097aedc9SJulie Hockett RecordInfo *F = InfoAsRecord(Infos[4].get()); 210b46131e5SDiego Astiazaran RecordInfo ExpectedF(EmptySID, /*Name=*/"F", /*Path=*/"GlobalNamespace"); 211b46131e5SDiego Astiazaran ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace", 212b46131e5SDiego Astiazaran InfoType::IT_namespace); 213edd690b0SVlad Serebrennikov ExpectedF.TagType = TagTypeKind::Struct; 214b1f01e27SJulie Hockett ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 215b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedF, F); 216b1f01e27SJulie Hockett 217097aedc9SJulie Hockett RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[6].get()); 218b1f01e27SJulie Hockett RecordInfo ExpectedRecordWithTemplateMethod(EmptySID); 219b1f01e27SJulie Hockett FunctionInfo TemplateMethod; 220b1f01e27SJulie Hockett TemplateMethod.Name = "TemplateMethod"; 221b1f01e27SJulie Hockett TemplateMethod.Parent = Reference(EmptySID, "F", InfoType::IT_record); 2220afc6085SBrett Wilson TemplateMethod.ReturnType = TypeInfo("void"); 223b1f01e27SJulie Hockett TemplateMethod.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); 224b1f01e27SJulie Hockett TemplateMethod.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record); 225b46131e5SDiego Astiazaran TemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace", 226b46131e5SDiego Astiazaran InfoType::IT_namespace); 227b1f01e27SJulie Hockett TemplateMethod.Access = AccessSpecifier::AS_public; 228b1f01e27SJulie Hockett TemplateMethod.IsMethod = true; 22921fb70c6SBrett Wilson ExpectedRecordWithTemplateMethod.Children.Functions.emplace_back( 230b1f01e27SJulie Hockett std::move(TemplateMethod)); 231b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedRecordWithTemplateMethod, RecordWithTemplateMethod); 232b1f01e27SJulie Hockett 233097aedc9SJulie Hockett RecordInfo *TemplatedRecord = InfoAsRecord(Infos[7].get()); 234b1f01e27SJulie Hockett RecordInfo ExpectedTemplatedRecord(EmptySID); 235b1f01e27SJulie Hockett FunctionInfo SpecializedTemplateMethod; 236b1f01e27SJulie Hockett SpecializedTemplateMethod.Name = "TemplateMethod"; 237b1f01e27SJulie Hockett SpecializedTemplateMethod.Parent = 238b1f01e27SJulie Hockett Reference(EmptySID, "F", InfoType::IT_record); 2390afc6085SBrett Wilson SpecializedTemplateMethod.ReturnType = TypeInfo("void"); 240b1f01e27SJulie Hockett SpecializedTemplateMethod.Loc.emplace_back(0, 241b1f01e27SJulie Hockett llvm::SmallString<16>{"test.cpp"}); 242b1f01e27SJulie Hockett SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "F", 243b1f01e27SJulie Hockett InfoType::IT_record); 244b46131e5SDiego Astiazaran SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace", 245b46131e5SDiego Astiazaran InfoType::IT_namespace); 246b1f01e27SJulie Hockett SpecializedTemplateMethod.Access = AccessSpecifier::AS_public; 247b1f01e27SJulie Hockett SpecializedTemplateMethod.IsMethod = true; 24821fb70c6SBrett Wilson ExpectedTemplatedRecord.Children.Functions.emplace_back( 249b1f01e27SJulie Hockett std::move(SpecializedTemplateMethod)); 250b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedTemplatedRecord, TemplatedRecord); 251b1f01e27SJulie Hockett 252097aedc9SJulie Hockett RecordInfo *G = InfoAsRecord(Infos[8].get()); 253b46131e5SDiego Astiazaran RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/"GlobalNamespace"); 254b46131e5SDiego Astiazaran ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace", 255b46131e5SDiego Astiazaran InfoType::IT_namespace); 256edd690b0SVlad Serebrennikov ExpectedG.TagType = TagTypeKind::Struct; 257b1f01e27SJulie Hockett ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 258b1f01e27SJulie Hockett ExpectedG.IsTypeDef = true; 259b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedG, G); 26068049b1aSJulie Hockett } 26168049b1aSJulie Hockett 26268049b1aSJulie Hockett // Test serialization of enum declarations. 26368049b1aSJulie Hockett TEST(SerializeTest, emitEnumInfo) { 26468049b1aSJulie Hockett EmittedInfoList Infos; 26568049b1aSJulie Hockett ExtractInfosFromCode("enum E { X, Y }; enum class G { A, B };", 2, 26668049b1aSJulie Hockett /*Public=*/false, Infos); 26768049b1aSJulie Hockett 26868049b1aSJulie Hockett NamespaceInfo *NamespaceWithEnum = InfoAsNamespace(Infos[0].get()); 26968049b1aSJulie Hockett NamespaceInfo ExpectedNamespaceWithEnum(EmptySID); 27068049b1aSJulie Hockett EnumInfo E; 27168049b1aSJulie Hockett E.Name = "E"; 27268049b1aSJulie Hockett E.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 273eaa7b324SBrett Wilson E.Members.emplace_back("X", "0"); 274eaa7b324SBrett Wilson E.Members.emplace_back("Y", "1"); 27521fb70c6SBrett Wilson ExpectedNamespaceWithEnum.Children.Enums.emplace_back(std::move(E)); 27668049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedNamespaceWithEnum, NamespaceWithEnum); 27768049b1aSJulie Hockett 27868049b1aSJulie Hockett NamespaceInfo *NamespaceWithScopedEnum = InfoAsNamespace(Infos[1].get()); 27968049b1aSJulie Hockett NamespaceInfo ExpectedNamespaceWithScopedEnum(EmptySID); 28068049b1aSJulie Hockett EnumInfo G; 28168049b1aSJulie Hockett G.Name = "G"; 28268049b1aSJulie Hockett G.Scoped = true; 28368049b1aSJulie Hockett G.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 284eaa7b324SBrett Wilson G.Members.emplace_back("A", "0"); 285eaa7b324SBrett Wilson G.Members.emplace_back("B", "1"); 28621fb70c6SBrett Wilson ExpectedNamespaceWithScopedEnum.Children.Enums.emplace_back(std::move(G)); 28768049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedNamespaceWithScopedEnum, NamespaceWithScopedEnum); 28868049b1aSJulie Hockett } 28968049b1aSJulie Hockett 29068049b1aSJulie Hockett TEST(SerializeTest, emitUndefinedRecordInfo) { 29168049b1aSJulie Hockett EmittedInfoList Infos; 292097aedc9SJulie Hockett ExtractInfosFromCode("class E;", 2, /*Public=*/false, Infos); 29368049b1aSJulie Hockett 29468049b1aSJulie Hockett RecordInfo *E = InfoAsRecord(Infos[0].get()); 295b46131e5SDiego Astiazaran RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace"); 296b46131e5SDiego Astiazaran ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace", 297b46131e5SDiego Astiazaran InfoType::IT_namespace); 298edd690b0SVlad Serebrennikov ExpectedE.TagType = TagTypeKind::Class; 29968049b1aSJulie Hockett ExpectedE.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); 30068049b1aSJulie Hockett CheckRecordInfo(&ExpectedE, E); 30168049b1aSJulie Hockett } 30268049b1aSJulie Hockett 30368049b1aSJulie Hockett TEST(SerializeTest, emitRecordMemberInfo) { 30468049b1aSJulie Hockett EmittedInfoList Infos; 305097aedc9SJulie Hockett ExtractInfosFromCode("struct E { int I; };", 2, /*Public=*/false, Infos); 30668049b1aSJulie Hockett 30768049b1aSJulie Hockett RecordInfo *E = InfoAsRecord(Infos[0].get()); 308b46131e5SDiego Astiazaran RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace"); 309b46131e5SDiego Astiazaran ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace", 310b46131e5SDiego Astiazaran InfoType::IT_namespace); 311edd690b0SVlad Serebrennikov ExpectedE.TagType = TagTypeKind::Struct; 31268049b1aSJulie Hockett ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 3130afc6085SBrett Wilson ExpectedE.Members.emplace_back(TypeInfo("int"), "I", 3140afc6085SBrett Wilson AccessSpecifier::AS_public); 31568049b1aSJulie Hockett CheckRecordInfo(&ExpectedE, E); 31668049b1aSJulie Hockett } 31768049b1aSJulie Hockett 31868049b1aSJulie Hockett TEST(SerializeTest, emitInternalRecordInfo) { 31968049b1aSJulie Hockett EmittedInfoList Infos; 320097aedc9SJulie Hockett ExtractInfosFromCode("class E { class G {}; };", 4, /*Public=*/false, Infos); 32168049b1aSJulie Hockett 32268049b1aSJulie Hockett RecordInfo *E = InfoAsRecord(Infos[0].get()); 323b46131e5SDiego Astiazaran RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace"); 324b46131e5SDiego Astiazaran ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace", 325b46131e5SDiego Astiazaran InfoType::IT_namespace); 32668049b1aSJulie Hockett ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 327edd690b0SVlad Serebrennikov ExpectedE.TagType = TagTypeKind::Class; 32868049b1aSJulie Hockett CheckRecordInfo(&ExpectedE, E); 32968049b1aSJulie Hockett 330097aedc9SJulie Hockett RecordInfo *G = InfoAsRecord(Infos[2].get()); 331b46131e5SDiego Astiazaran llvm::SmallString<128> ExpectedGPath("GlobalNamespace/E"); 332b46131e5SDiego Astiazaran llvm::sys::path::native(ExpectedGPath); 333b46131e5SDiego Astiazaran RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/ExpectedGPath); 33468049b1aSJulie Hockett ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 335edd690b0SVlad Serebrennikov ExpectedG.TagType = TagTypeKind::Class; 33668049b1aSJulie Hockett ExpectedG.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); 337b46131e5SDiego Astiazaran ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace", 338b46131e5SDiego Astiazaran InfoType::IT_namespace); 33968049b1aSJulie Hockett CheckRecordInfo(&ExpectedG, G); 34068049b1aSJulie Hockett } 34168049b1aSJulie Hockett 34268049b1aSJulie Hockett TEST(SerializeTest, emitPublicAnonymousNamespaceInfo) { 34368049b1aSJulie Hockett EmittedInfoList Infos; 34468049b1aSJulie Hockett ExtractInfosFromCode("namespace { class A; }", 0, /*Public=*/true, Infos); 34568049b1aSJulie Hockett } 34668049b1aSJulie Hockett 34768049b1aSJulie Hockett TEST(SerializeTest, emitPublicFunctionInternalInfo) { 34868049b1aSJulie Hockett EmittedInfoList Infos; 34968049b1aSJulie Hockett ExtractInfosFromCode("int F() { class G {}; return 0; };", 1, /*Public=*/true, 35068049b1aSJulie Hockett Infos); 35168049b1aSJulie Hockett 35268049b1aSJulie Hockett NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); 35368049b1aSJulie Hockett NamespaceInfo ExpectedBWithFunction(EmptySID); 35468049b1aSJulie Hockett FunctionInfo F; 35568049b1aSJulie Hockett F.Name = "F"; 3560afc6085SBrett Wilson F.ReturnType = TypeInfo("int"); 35768049b1aSJulie Hockett F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 3586a29ae4bSDiego Astiazaran F.Access = AccessSpecifier::AS_none; 35921fb70c6SBrett Wilson ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F)); 36068049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); 36168049b1aSJulie Hockett } 36268049b1aSJulie Hockett 36368049b1aSJulie Hockett TEST(SerializeTest, emitInlinedFunctionInfo) { 36468049b1aSJulie Hockett EmittedInfoList Infos; 36568049b1aSJulie Hockett ExtractInfosFromCode("inline void F(int I) { };", 1, /*Public=*/true, Infos); 36668049b1aSJulie Hockett 36768049b1aSJulie Hockett NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); 36868049b1aSJulie Hockett NamespaceInfo ExpectedBWithFunction(EmptySID); 36968049b1aSJulie Hockett FunctionInfo F; 37068049b1aSJulie Hockett F.Name = "F"; 3710afc6085SBrett Wilson F.ReturnType = TypeInfo("void"); 37268049b1aSJulie Hockett F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 3730afc6085SBrett Wilson F.Params.emplace_back(TypeInfo("int"), "I"); 3746a29ae4bSDiego Astiazaran F.Access = AccessSpecifier::AS_none; 37521fb70c6SBrett Wilson ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F)); 37668049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); 37768049b1aSJulie Hockett } 37868049b1aSJulie Hockett 379ba3d595fSDiego Astiazaran TEST(SerializeTest, emitInheritedRecordInfo) { 38068049b1aSJulie Hockett EmittedInfoList Infos; 381ba3d595fSDiego Astiazaran ExtractInfosFromCode(R"raw(class F { protected: void set(int N); }; 382ba3d595fSDiego Astiazaran class G { public: int get() { return 1; } protected: int I; }; 383b1f01e27SJulie Hockett class E : public F, virtual private G {}; 384ba3d595fSDiego Astiazaran class H : private E {}; 385b1f01e27SJulie Hockett template <typename T> 386ba3d595fSDiego Astiazaran class I {} ; 387ba3d595fSDiego Astiazaran class J : public I<int> {} ;)raw", 388ba3d595fSDiego Astiazaran 14, /*Public=*/false, Infos); 38968049b1aSJulie Hockett 39068049b1aSJulie Hockett RecordInfo *F = InfoAsRecord(Infos[0].get()); 391b46131e5SDiego Astiazaran RecordInfo ExpectedF(EmptySID, /*Name=*/"F", /*Path=*/"GlobalNamespace"); 392b46131e5SDiego Astiazaran ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace", 3934a68babdSBrett Wilson InfoType::IT_namespace, ""); 394edd690b0SVlad Serebrennikov ExpectedF.TagType = TagTypeKind::Class; 39568049b1aSJulie Hockett ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 39668049b1aSJulie Hockett CheckRecordInfo(&ExpectedF, F); 39768049b1aSJulie Hockett 398ba3d595fSDiego Astiazaran RecordInfo *G = InfoAsRecord(Infos[3].get()); 399b46131e5SDiego Astiazaran RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/"GlobalNamespace"); 400b46131e5SDiego Astiazaran ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace", 401b46131e5SDiego Astiazaran InfoType::IT_namespace); 402edd690b0SVlad Serebrennikov ExpectedG.TagType = TagTypeKind::Class; 40368049b1aSJulie Hockett ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 4040afc6085SBrett Wilson ExpectedG.Members.emplace_back(TypeInfo("int"), "I", 4050afc6085SBrett Wilson AccessSpecifier::AS_protected); 40668049b1aSJulie Hockett CheckRecordInfo(&ExpectedG, G); 40768049b1aSJulie Hockett 408ba3d595fSDiego Astiazaran RecordInfo *E = InfoAsRecord(Infos[6].get()); 409b46131e5SDiego Astiazaran RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace"); 410b46131e5SDiego Astiazaran ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace", 411b46131e5SDiego Astiazaran InfoType::IT_namespace); 412b46131e5SDiego Astiazaran ExpectedE.Parents.emplace_back(EmptySID, /*Name=*/"F", InfoType::IT_record, 4134a68babdSBrett Wilson /*QualName=*/"", /*Path*=*/"GlobalNamespace"); 4144a68babdSBrett Wilson ExpectedE.VirtualParents.emplace_back(EmptySID, /*Name=*/"G", 4154a68babdSBrett Wilson InfoType::IT_record, /*QualName=*/"G", 416b46131e5SDiego Astiazaran /*Path*=*/"GlobalNamespace"); 417b46131e5SDiego Astiazaran ExpectedE.Bases.emplace_back(EmptySID, /*Name=*/"F", 418b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", false, 419ba3d595fSDiego Astiazaran AccessSpecifier::AS_public, true); 420ba3d595fSDiego Astiazaran FunctionInfo FunctionSet; 421ba3d595fSDiego Astiazaran FunctionSet.Name = "set"; 4220afc6085SBrett Wilson FunctionSet.ReturnType = TypeInfo("void"); 423ba3d595fSDiego Astiazaran FunctionSet.Loc.emplace_back(); 4240afc6085SBrett Wilson FunctionSet.Params.emplace_back(TypeInfo("int"), "N"); 425ba3d595fSDiego Astiazaran FunctionSet.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record); 426b46131e5SDiego Astiazaran FunctionSet.Namespace.emplace_back(EmptySID, "GlobalNamespace", 427b46131e5SDiego Astiazaran InfoType::IT_namespace); 428ba3d595fSDiego Astiazaran FunctionSet.Access = AccessSpecifier::AS_protected; 429ba3d595fSDiego Astiazaran FunctionSet.IsMethod = true; 43021fb70c6SBrett Wilson ExpectedE.Bases.back().Children.Functions.emplace_back( 43121fb70c6SBrett Wilson std::move(FunctionSet)); 432b46131e5SDiego Astiazaran ExpectedE.Bases.emplace_back(EmptySID, /*Name=*/"G", 433b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", true, 434ba3d595fSDiego Astiazaran AccessSpecifier::AS_private, true); 435ba3d595fSDiego Astiazaran FunctionInfo FunctionGet; 436ba3d595fSDiego Astiazaran FunctionGet.Name = "get"; 4370afc6085SBrett Wilson FunctionGet.ReturnType = TypeInfo("int"); 438ba3d595fSDiego Astiazaran FunctionGet.DefLoc = Location(); 439ba3d595fSDiego Astiazaran FunctionGet.Namespace.emplace_back(EmptySID, "G", InfoType::IT_record); 440b46131e5SDiego Astiazaran FunctionGet.Namespace.emplace_back(EmptySID, "GlobalNamespace", 441b46131e5SDiego Astiazaran InfoType::IT_namespace); 442ba3d595fSDiego Astiazaran FunctionGet.Access = AccessSpecifier::AS_private; 443ba3d595fSDiego Astiazaran FunctionGet.IsMethod = true; 44421fb70c6SBrett Wilson ExpectedE.Bases.back().Children.Functions.emplace_back( 44521fb70c6SBrett Wilson std::move(FunctionGet)); 4460afc6085SBrett Wilson ExpectedE.Bases.back().Members.emplace_back(TypeInfo("int"), "I", 447ba3d595fSDiego Astiazaran AccessSpecifier::AS_private); 44868049b1aSJulie Hockett ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 449edd690b0SVlad Serebrennikov ExpectedE.TagType = TagTypeKind::Class; 45068049b1aSJulie Hockett CheckRecordInfo(&ExpectedE, E); 451b1f01e27SJulie Hockett 452ba3d595fSDiego Astiazaran RecordInfo *H = InfoAsRecord(Infos[8].get()); 453b46131e5SDiego Astiazaran RecordInfo ExpectedH(EmptySID, /*Name=*/"H", /*Path=*/"GlobalNamespace"); 454b46131e5SDiego Astiazaran ExpectedH.Namespace.emplace_back(EmptySID, "GlobalNamespace", 455b46131e5SDiego Astiazaran InfoType::IT_namespace); 456edd690b0SVlad Serebrennikov ExpectedH.TagType = TagTypeKind::Class; 457b1f01e27SJulie Hockett ExpectedH.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 458b46131e5SDiego Astiazaran ExpectedH.Parents.emplace_back(EmptySID, /*Name=*/"E", InfoType::IT_record, 4594a68babdSBrett Wilson /*QualName=*/"E", /*Path=*/"GlobalNamespace"); 4604a68babdSBrett Wilson ExpectedH.VirtualParents.emplace_back(EmptySID, /*Name=*/"G", 4614a68babdSBrett Wilson InfoType::IT_record, /*QualName=*/"G", 462b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace"); 463b46131e5SDiego Astiazaran ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"E", 464b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", false, 465ba3d595fSDiego Astiazaran AccessSpecifier::AS_private, true); 466b46131e5SDiego Astiazaran ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"F", 467b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", false, 468ba3d595fSDiego Astiazaran AccessSpecifier::AS_private, false); 469ba3d595fSDiego Astiazaran FunctionInfo FunctionSetNew; 470ba3d595fSDiego Astiazaran FunctionSetNew.Name = "set"; 4710afc6085SBrett Wilson FunctionSetNew.ReturnType = TypeInfo("void"); 472ba3d595fSDiego Astiazaran FunctionSetNew.Loc.emplace_back(); 4730afc6085SBrett Wilson FunctionSetNew.Params.emplace_back(TypeInfo("int"), "N"); 474ba3d595fSDiego Astiazaran FunctionSetNew.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record); 475b46131e5SDiego Astiazaran FunctionSetNew.Namespace.emplace_back(EmptySID, "GlobalNamespace", 476b46131e5SDiego Astiazaran InfoType::IT_namespace); 477ba3d595fSDiego Astiazaran FunctionSetNew.Access = AccessSpecifier::AS_private; 478ba3d595fSDiego Astiazaran FunctionSetNew.IsMethod = true; 47921fb70c6SBrett Wilson ExpectedH.Bases.back().Children.Functions.emplace_back( 48021fb70c6SBrett Wilson std::move(FunctionSetNew)); 481b46131e5SDiego Astiazaran ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"G", 482b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", true, 483ba3d595fSDiego Astiazaran AccessSpecifier::AS_private, false); 484ba3d595fSDiego Astiazaran FunctionInfo FunctionGetNew; 485ba3d595fSDiego Astiazaran FunctionGetNew.Name = "get"; 4860afc6085SBrett Wilson FunctionGetNew.ReturnType = TypeInfo("int"); 487ba3d595fSDiego Astiazaran FunctionGetNew.DefLoc = Location(); 488ba3d595fSDiego Astiazaran FunctionGetNew.Namespace.emplace_back(EmptySID, "G", InfoType::IT_record); 489b46131e5SDiego Astiazaran FunctionGetNew.Namespace.emplace_back(EmptySID, "GlobalNamespace", 490b46131e5SDiego Astiazaran InfoType::IT_namespace); 491ba3d595fSDiego Astiazaran FunctionGetNew.Access = AccessSpecifier::AS_private; 492ba3d595fSDiego Astiazaran FunctionGetNew.IsMethod = true; 49321fb70c6SBrett Wilson ExpectedH.Bases.back().Children.Functions.emplace_back( 49421fb70c6SBrett Wilson std::move(FunctionGetNew)); 4950afc6085SBrett Wilson ExpectedH.Bases.back().Members.emplace_back(TypeInfo("int"), "I", 496ba3d595fSDiego Astiazaran AccessSpecifier::AS_private); 497b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedH, H); 498b1f01e27SJulie Hockett 499ba3d595fSDiego Astiazaran RecordInfo *I = InfoAsRecord(Infos[10].get()); 500b46131e5SDiego Astiazaran RecordInfo ExpectedI(EmptySID, /*Name=*/"I", /*Path=*/"GlobalNamespace"); 501b46131e5SDiego Astiazaran ExpectedI.Namespace.emplace_back(EmptySID, "GlobalNamespace", 502b46131e5SDiego Astiazaran InfoType::IT_namespace); 503edd690b0SVlad Serebrennikov ExpectedI.TagType = TagTypeKind::Class; 504ba3d595fSDiego Astiazaran ExpectedI.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 505b1f01e27SJulie Hockett CheckRecordInfo(&ExpectedI, I); 506ba3d595fSDiego Astiazaran 507ba3d595fSDiego Astiazaran RecordInfo *J = InfoAsRecord(Infos[12].get()); 508b46131e5SDiego Astiazaran RecordInfo ExpectedJ(EmptySID, /*Name=*/"J", /*Path=*/"GlobalNamespace"); 509b46131e5SDiego Astiazaran ExpectedJ.Namespace.emplace_back(EmptySID, "GlobalNamespace", 510b46131e5SDiego Astiazaran InfoType::IT_namespace); 511b46131e5SDiego Astiazaran ExpectedJ.Parents.emplace_back(EmptySID, /*Name=*/"I<int>", 512b46131e5SDiego Astiazaran InfoType::IT_record); 513b46131e5SDiego Astiazaran ExpectedJ.Bases.emplace_back(EmptySID, /*Name=*/"I<int>", 514b46131e5SDiego Astiazaran /*Path=*/"GlobalNamespace", false, 515ba3d595fSDiego Astiazaran AccessSpecifier::AS_public, true); 516ba3d595fSDiego Astiazaran ExpectedJ.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); 517edd690b0SVlad Serebrennikov ExpectedJ.TagType = TagTypeKind::Class; 518ba3d595fSDiego Astiazaran CheckRecordInfo(&ExpectedJ, J); 51968049b1aSJulie Hockett } 52068049b1aSJulie Hockett 52168049b1aSJulie Hockett TEST(SerializeTest, emitModulePublicLFunctions) { 52268049b1aSJulie Hockett EmittedInfoList Infos; 52368049b1aSJulie Hockett std::vector<std::string> Args; 52468049b1aSJulie Hockett Args.push_back("-fmodules-ts"); 52568049b1aSJulie Hockett ExtractInfosFromCodeWithArgs(R"raw(export module M; 526e191086bSBrett Wilson int moduleFunction(int x, double d = 3.2 - 1.0); 52768049b1aSJulie Hockett static int staticModuleFunction(int x); 52868049b1aSJulie Hockett export double exportedModuleFunction(double y);)raw", 52968049b1aSJulie Hockett 2, /*Public=*/true, Infos, Args); 53068049b1aSJulie Hockett 53168049b1aSJulie Hockett NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); 53268049b1aSJulie Hockett NamespaceInfo ExpectedBWithFunction(EmptySID); 53368049b1aSJulie Hockett FunctionInfo F; 53468049b1aSJulie Hockett F.Name = "moduleFunction"; 5350afc6085SBrett Wilson F.ReturnType = TypeInfo("int"); 53668049b1aSJulie Hockett F.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); 5370afc6085SBrett Wilson F.Params.emplace_back(TypeInfo("int"), "x"); 5380afc6085SBrett Wilson F.Params.emplace_back(TypeInfo("double"), "d"); 539e191086bSBrett Wilson F.Params.back().DefaultValue = "3.2 - 1.0"; 5406a29ae4bSDiego Astiazaran F.Access = AccessSpecifier::AS_none; 54121fb70c6SBrett Wilson ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F)); 54268049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); 54368049b1aSJulie Hockett 54468049b1aSJulie Hockett NamespaceInfo *BWithExportedFunction = InfoAsNamespace(Infos[1].get()); 54568049b1aSJulie Hockett NamespaceInfo ExpectedBWithExportedFunction(EmptySID); 54668049b1aSJulie Hockett FunctionInfo ExportedF; 54768049b1aSJulie Hockett ExportedF.Name = "exportedModuleFunction"; 5480afc6085SBrett Wilson ExportedF.ReturnType = 5490afc6085SBrett Wilson TypeInfo(Reference(EmptySID, "double", InfoType::IT_default)); 55068049b1aSJulie Hockett ExportedF.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); 5510afc6085SBrett Wilson ExportedF.Params.emplace_back(TypeInfo("double"), "y"); 5526a29ae4bSDiego Astiazaran ExportedF.Access = AccessSpecifier::AS_none; 55321fb70c6SBrett Wilson ExpectedBWithExportedFunction.Children.Functions.emplace_back( 55468049b1aSJulie Hockett std::move(ExportedF)); 55568049b1aSJulie Hockett CheckNamespaceInfo(&ExpectedBWithExportedFunction, BWithExportedFunction); 55668049b1aSJulie Hockett } 55768049b1aSJulie Hockett 558097aedc9SJulie Hockett // Test serialization of child records in namespaces and other records 559097aedc9SJulie Hockett TEST(SerializeTest, emitChildRecords) { 560097aedc9SJulie Hockett EmittedInfoList Infos; 561097aedc9SJulie Hockett ExtractInfosFromCode("class A { class B {}; }; namespace { class C {}; } ", 8, 562097aedc9SJulie Hockett /*Public=*/false, Infos); 563097aedc9SJulie Hockett 564097aedc9SJulie Hockett NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get()); 565097aedc9SJulie Hockett NamespaceInfo ExpectedParentA(EmptySID); 56621fb70c6SBrett Wilson ExpectedParentA.Children.Records.emplace_back( 5674a68babdSBrett Wilson EmptySID, "A", InfoType::IT_record, "A", "GlobalNamespace"); 568097aedc9SJulie Hockett CheckNamespaceInfo(&ExpectedParentA, ParentA); 569097aedc9SJulie Hockett 570097aedc9SJulie Hockett RecordInfo *ParentB = InfoAsRecord(Infos[3].get()); 571097aedc9SJulie Hockett RecordInfo ExpectedParentB(EmptySID); 572b46131e5SDiego Astiazaran llvm::SmallString<128> ExpectedParentBPath("GlobalNamespace/A"); 573b46131e5SDiego Astiazaran llvm::sys::path::native(ExpectedParentBPath); 57421fb70c6SBrett Wilson ExpectedParentB.Children.Records.emplace_back( 5754a68babdSBrett Wilson EmptySID, "B", InfoType::IT_record, "A::B", ExpectedParentBPath); 576097aedc9SJulie Hockett CheckRecordInfo(&ExpectedParentB, ParentB); 577097aedc9SJulie Hockett 578097aedc9SJulie Hockett NamespaceInfo *ParentC = InfoAsNamespace(Infos[7].get()); 579097aedc9SJulie Hockett NamespaceInfo ExpectedParentC(EmptySID); 58021fb70c6SBrett Wilson ExpectedParentC.Children.Records.emplace_back( 5814a68babdSBrett Wilson EmptySID, "C", InfoType::IT_record, "C", "@nonymous_namespace"); 582097aedc9SJulie Hockett CheckNamespaceInfo(&ExpectedParentC, ParentC); 583097aedc9SJulie Hockett } 584097aedc9SJulie Hockett 585097aedc9SJulie Hockett // Test serialization of child namespaces 586097aedc9SJulie Hockett TEST(SerializeTest, emitChildNamespaces) { 587097aedc9SJulie Hockett EmittedInfoList Infos; 588097aedc9SJulie Hockett ExtractInfosFromCode("namespace A { namespace B { } }", 4, /*Public=*/false, 589097aedc9SJulie Hockett Infos); 590097aedc9SJulie Hockett 591097aedc9SJulie Hockett NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get()); 592097aedc9SJulie Hockett NamespaceInfo ExpectedParentA(EmptySID); 59321fb70c6SBrett Wilson ExpectedParentA.Children.Namespaces.emplace_back(EmptySID, "A", 594097aedc9SJulie Hockett InfoType::IT_namespace); 595097aedc9SJulie Hockett CheckNamespaceInfo(&ExpectedParentA, ParentA); 596097aedc9SJulie Hockett 597097aedc9SJulie Hockett NamespaceInfo *ParentB = InfoAsNamespace(Infos[3].get()); 598097aedc9SJulie Hockett NamespaceInfo ExpectedParentB(EmptySID); 5994a68babdSBrett Wilson ExpectedParentB.Children.Namespaces.emplace_back( 6004a68babdSBrett Wilson EmptySID, "B", InfoType::IT_namespace, "A::B", "A"); 601097aedc9SJulie Hockett CheckNamespaceInfo(&ExpectedParentB, ParentB); 602097aedc9SJulie Hockett } 603097aedc9SJulie Hockett 60421fb70c6SBrett Wilson TEST(SerializeTests, emitTypedefs) { 60521fb70c6SBrett Wilson EmittedInfoList Infos; 60621fb70c6SBrett Wilson ExtractInfosFromCode("typedef int MyInt; using MyDouble = double;", 2, 60721fb70c6SBrett Wilson /*Public=*/false, Infos); 60821fb70c6SBrett Wilson 60921fb70c6SBrett Wilson // First info will be the global namespace with the typedef in it. 61021fb70c6SBrett Wilson NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0].get()); 61121fb70c6SBrett Wilson ASSERT_EQ(1u, GlobalNS1->Children.Typedefs.size()); 61221fb70c6SBrett Wilson 61321fb70c6SBrett Wilson const TypedefInfo &FirstTD = GlobalNS1->Children.Typedefs[0]; 61421fb70c6SBrett Wilson EXPECT_EQ("MyInt", FirstTD.Name); 61521fb70c6SBrett Wilson EXPECT_FALSE(FirstTD.IsUsing); 61621fb70c6SBrett Wilson EXPECT_EQ("int", FirstTD.Underlying.Type.Name); 61721fb70c6SBrett Wilson 61821fb70c6SBrett Wilson // The second will be another global namespace with the using in it (the 61921fb70c6SBrett Wilson // global namespace is duplicated because the items haven't been merged at the 62021fb70c6SBrett Wilson // serialization phase of processing). 62121fb70c6SBrett Wilson NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1].get()); 62221fb70c6SBrett Wilson ASSERT_EQ(1u, GlobalNS2->Children.Typedefs.size()); 62321fb70c6SBrett Wilson 62421fb70c6SBrett Wilson // Second is the "using" typedef. 62521fb70c6SBrett Wilson const TypedefInfo &SecondTD = GlobalNS2->Children.Typedefs[0]; 62621fb70c6SBrett Wilson EXPECT_EQ("MyDouble", SecondTD.Name); 62721fb70c6SBrett Wilson EXPECT_TRUE(SecondTD.IsUsing); 62821fb70c6SBrett Wilson EXPECT_EQ("double", SecondTD.Underlying.Type.Name); 62921fb70c6SBrett Wilson } 63021fb70c6SBrett Wilson 6314a68babdSBrett Wilson TEST(SerializeTests, emitFunctionTemplate) { 6324a68babdSBrett Wilson EmittedInfoList Infos; 6334a68babdSBrett Wilson // A template and a specialization. 634*2b932bc1SPaul Kirth ExtractInfosFromCode("template<typename T = int> bool GetFoo(T);\n" 635*2b932bc1SPaul Kirth "template<> bool GetFoo<bool>(bool);", 6364a68babdSBrett Wilson 2, 6374a68babdSBrett Wilson /*Public=*/false, Infos); 6384a68babdSBrett Wilson 6394a68babdSBrett Wilson // First info will be the global namespace. 6404a68babdSBrett Wilson NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0].get()); 6414a68babdSBrett Wilson ASSERT_EQ(1u, GlobalNS1->Children.Functions.size()); 6424a68babdSBrett Wilson 6434a68babdSBrett Wilson const FunctionInfo &Func1 = GlobalNS1->Children.Functions[0]; 6444a68babdSBrett Wilson EXPECT_EQ("GetFoo", Func1.Name); 6454a68babdSBrett Wilson ASSERT_TRUE(Func1.Template); 6464a68babdSBrett Wilson EXPECT_FALSE(Func1.Template->Specialization); // Not a specialization. 6474a68babdSBrett Wilson 6484a68babdSBrett Wilson // Template parameter. 6494a68babdSBrett Wilson ASSERT_EQ(1u, Func1.Template->Params.size()); 6504a68babdSBrett Wilson EXPECT_EQ("typename T = int", Func1.Template->Params[0].Contents); 6514a68babdSBrett Wilson 6524a68babdSBrett Wilson // The second will be another global namespace with the function in it (the 6534a68babdSBrett Wilson // global namespace is duplicated because the items haven't been merged at the 6544a68babdSBrett Wilson // serialization phase of processing). 6554a68babdSBrett Wilson NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1].get()); 6564a68babdSBrett Wilson ASSERT_EQ(1u, GlobalNS2->Children.Functions.size()); 6574a68babdSBrett Wilson 6584a68babdSBrett Wilson // This one is a template specialization. 6594a68babdSBrett Wilson const FunctionInfo &Func2 = GlobalNS2->Children.Functions[0]; 6604a68babdSBrett Wilson EXPECT_EQ("GetFoo", Func2.Name); 6614a68babdSBrett Wilson ASSERT_TRUE(Func2.Template); 6624a68babdSBrett Wilson EXPECT_TRUE(Func2.Template->Params.empty()); // No template params. 6634a68babdSBrett Wilson ASSERT_TRUE(Func2.Template->Specialization); 6644a68babdSBrett Wilson 6654a68babdSBrett Wilson // Specialization values. 6664a68babdSBrett Wilson ASSERT_EQ(1u, Func2.Template->Specialization->Params.size()); 6674a68babdSBrett Wilson EXPECT_EQ("bool", Func2.Template->Specialization->Params[0].Contents); 6684a68babdSBrett Wilson EXPECT_EQ(Func1.USR, Func2.Template->Specialization->SpecializationOf); 669*2b932bc1SPaul Kirth 670*2b932bc1SPaul Kirth EXPECT_EQ("bool", Func2.ReturnType.Type.Name); 6714a68babdSBrett Wilson } 6724a68babdSBrett Wilson 6734a68babdSBrett Wilson TEST(SerializeTests, emitClassTemplate) { 6744a68babdSBrett Wilson EmittedInfoList Infos; 6754a68babdSBrett Wilson // This will generate 2x the number of infos: each Record will be followed by 6764a68babdSBrett Wilson // a copy of the global namespace containing it (this test checks the data 6774a68babdSBrett Wilson // pre-merge). 6784a68babdSBrett Wilson ExtractInfosFromCode( 6794a68babdSBrett Wilson "template<int I> class MyTemplate { int i[I]; };\n" 6804a68babdSBrett Wilson "template<> class MyTemplate<0> {};\n" 6814a68babdSBrett Wilson "template<typename T, int U = 1> class OtherTemplate {};\n" 6824a68babdSBrett Wilson "template<int U> class OtherTemplate<MyTemplate<0>, U> {};", 6834a68babdSBrett Wilson 8, 6844a68babdSBrett Wilson /*Public=*/false, Infos); 6854a68babdSBrett Wilson 6864a68babdSBrett Wilson // First record. 6874a68babdSBrett Wilson const RecordInfo *Rec1 = InfoAsRecord(Infos[0].get()); 6884a68babdSBrett Wilson EXPECT_EQ("MyTemplate", Rec1->Name); 6894a68babdSBrett Wilson ASSERT_TRUE(Rec1->Template); 6904a68babdSBrett Wilson EXPECT_FALSE(Rec1->Template->Specialization); // Not a specialization. 6914a68babdSBrett Wilson 6924a68babdSBrett Wilson // First record template parameter. 6934a68babdSBrett Wilson ASSERT_EQ(1u, Rec1->Template->Params.size()); 6944a68babdSBrett Wilson EXPECT_EQ("int I", Rec1->Template->Params[0].Contents); 6954a68babdSBrett Wilson 6964a68babdSBrett Wilson // Second record. 6974a68babdSBrett Wilson const RecordInfo *Rec2 = InfoAsRecord(Infos[2].get()); 6984a68babdSBrett Wilson EXPECT_EQ("MyTemplate", Rec2->Name); 6994a68babdSBrett Wilson ASSERT_TRUE(Rec2->Template); 7004a68babdSBrett Wilson EXPECT_TRUE(Rec2->Template->Params.empty()); // No template params. 7014a68babdSBrett Wilson ASSERT_TRUE(Rec2->Template->Specialization); 7024a68babdSBrett Wilson 7034a68babdSBrett Wilson // Second record specialization values. 7044a68babdSBrett Wilson ASSERT_EQ(1u, Rec2->Template->Specialization->Params.size()); 7054a68babdSBrett Wilson EXPECT_EQ("0", Rec2->Template->Specialization->Params[0].Contents); 7064a68babdSBrett Wilson EXPECT_EQ(Rec1->USR, Rec2->Template->Specialization->SpecializationOf); 7074a68babdSBrett Wilson 7084a68babdSBrett Wilson // Third record. 7094a68babdSBrett Wilson const RecordInfo *Rec3 = InfoAsRecord(Infos[4].get()); 7104a68babdSBrett Wilson EXPECT_EQ("OtherTemplate", Rec3->Name); 7114a68babdSBrett Wilson ASSERT_TRUE(Rec3->Template); 7124a68babdSBrett Wilson 7134a68babdSBrett Wilson // Third record template parameters. 7144a68babdSBrett Wilson ASSERT_EQ(2u, Rec3->Template->Params.size()); 7154a68babdSBrett Wilson EXPECT_EQ("typename T", Rec3->Template->Params[0].Contents); 7164a68babdSBrett Wilson EXPECT_EQ("int U = 1", Rec3->Template->Params[1].Contents); 7174a68babdSBrett Wilson 7184a68babdSBrett Wilson // Fourth record. 7194a68babdSBrett Wilson const RecordInfo *Rec4 = InfoAsRecord(Infos[6].get()); 7204a68babdSBrett Wilson EXPECT_EQ("OtherTemplate", Rec3->Name); 7214a68babdSBrett Wilson ASSERT_TRUE(Rec4->Template); 7224a68babdSBrett Wilson ASSERT_TRUE(Rec4->Template->Specialization); 7234a68babdSBrett Wilson 7244a68babdSBrett Wilson // Fourth record template + specialization parameters. 7254a68babdSBrett Wilson ASSERT_EQ(1u, Rec4->Template->Params.size()); 7264a68babdSBrett Wilson EXPECT_EQ("int U", Rec4->Template->Params[0].Contents); 7274a68babdSBrett Wilson ASSERT_EQ(2u, Rec4->Template->Specialization->Params.size()); 7284a68babdSBrett Wilson EXPECT_EQ("MyTemplate<0>", 7294a68babdSBrett Wilson Rec4->Template->Specialization->Params[0].Contents); 7304a68babdSBrett Wilson EXPECT_EQ("U", Rec4->Template->Specialization->Params[1].Contents); 7314a68babdSBrett Wilson } 7324a68babdSBrett Wilson 73368049b1aSJulie Hockett } // namespace doc 73468049b1aSJulie Hockett } // end namespace clang 735