Hi Julie, clang 3.6.0 complains on this commit:
/usr/bin/clang++ -march=corei7 -DGTEST_HAS_RTTI=0 -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_LANG_CXX11=1 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools/clang/tools/extra/unittests/clang-doc -I../tools/clang/tools/extra/unittests/clang-doc -I../tools/clang/include -Itools/clang/include -I/usr/include/libxml2 -Iinclude -I../include -I../tools/clang/tools/extra/clang-doc -I../utils/unittest/googletest/include -I../utils/unittest/googlemock/include -I/proj/flexasic/app/valgrind/3.11.0/include -fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -UNDEBUG -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -fno-exceptions -fno-rtti -MMD -MT tools/clang/tools/extra/unittests/clang-doc/CMakeFiles/ClangDocTests.dir/BitcodeTest.cpp.o -MF tools/clang/tools/extra/unittests/clang-doc/CMakeFiles/ClangDocTests.dir/BitcodeTest.cpp.o.d -o tools/clang/tools/extra/unittests/clang-doc/CMakeFiles/ClangDocTests.dir/BitcodeTest.cpp.o -c ../tools/clang/tools/extra/unittests/clang-doc/BitcodeTest.cpp In file included from ../tools/clang/tools/extra/unittests/clang-doc/BitcodeTest.cpp:12: ../tools/clang/tools/extra/unittests/clang-doc/ClangDocTest.h:25:14: error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces] SymbolID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { } 1 error generated. Regards, Mikael On 10/17/2018 01:06 AM, Julie Hockett via cfe-commits wrote: > Author: juliehockett > Date: Tue Oct 16 16:06:42 2018 > New Revision: 344650 > > URL: http://llvm.org/viewvc/llvm-project?rev=344650&view=rev > Log: > [clang-doc] Add unit tests for serialization > > Adds unit tests for the Serialize library. > > This is part of a move to convert clang-doc's tests to a more > maintainable unit test framework, with a smaller number of integration > tests to maintain and more granular failure feedback. > > Differential Revision: https://reviews.llvm.org/D53081 > > Added: > clang-tools-extra/trunk/unittests/clang-doc/ > clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt > clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp > clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.h > clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp > Modified: > clang-tools-extra/trunk/unittests/CMakeLists.txt > > Modified: clang-tools-extra/trunk/unittests/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/CMakeLists.txt?rev=344650&r1=344649&r2=344650&view=diff > ============================================================================== > --- clang-tools-extra/trunk/unittests/CMakeLists.txt (original) > +++ clang-tools-extra/trunk/unittests/CMakeLists.txt Tue Oct 16 16:06:42 2018 > @@ -16,6 +16,7 @@ endif() > > add_subdirectory(change-namespace) > add_subdirectory(clang-apply-replacements) > +add_subdirectory(clang-doc) > add_subdirectory(clang-move) > add_subdirectory(clang-query) > add_subdirectory(clang-tidy) > > Added: clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt?rev=344650&view=auto > ============================================================================== > --- clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt (added) > +++ clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt Tue Oct 16 > 16:06:42 2018 > @@ -0,0 +1,29 @@ > +set(LLVM_LINK_COMPONENTS > + support > + BitReader > + BitWriter > + ) > + > +get_filename_component(CLANG_DOC_SOURCE_DIR > + ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-doc REALPATH) > +include_directories( > + ${CLANG_DOC_SOURCE_DIR} > + ) > + > +add_extra_unittest(ClangDocTests > + ClangDocTest.cpp > + SerializeTest.cpp > + ) > + > +target_link_libraries(ClangDocTests > + PRIVATE > + clangAST > + clangASTMatchers > + clangBasic > + clangDoc > + clangFormat > + clangFrontend > + clangRewrite > + clangTooling > + clangToolingCore > + ) > > Added: clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp?rev=344650&view=auto > ============================================================================== > --- clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp (added) > +++ clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp Tue Oct 16 > 16:06:42 2018 > @@ -0,0 +1,182 @@ > +//===-- clang-doc/ClangDocTest.cpp > ----------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "Representation.h" > +#include "clang/AST/RecursiveASTVisitor.h" > +#include "gtest/gtest.h" > + > +namespace clang { > +namespace doc { > + > +NamespaceInfo *InfoAsNamespace(Info *I) { > + assert(I->IT == InfoType::IT_namespace); > + return static_cast<NamespaceInfo *>(I); > +} > + > +RecordInfo *InfoAsRecord(Info *I) { > + assert(I->IT == InfoType::IT_record); > + return static_cast<RecordInfo *>(I); > +} > + > +FunctionInfo *InfoAsFunction(Info *I) { > + assert(I->IT == InfoType::IT_function); > + return static_cast<FunctionInfo *>(I); > +} > + > +EnumInfo *InfoAsEnum(Info *I) { > + assert(I->IT == InfoType::IT_enum); > + return static_cast<EnumInfo *>(I); > +} > + > +void CheckCommentInfo(CommentInfo &Expected, CommentInfo &Actual) { > + EXPECT_EQ(Expected.Kind, Actual.Kind); > + EXPECT_EQ(Expected.Text, Actual.Text); > + EXPECT_EQ(Expected.Name, Actual.Name); > + EXPECT_EQ(Expected.Direction, Actual.Direction); > + EXPECT_EQ(Expected.ParamName, Actual.ParamName); > + EXPECT_EQ(Expected.CloseName, Actual.CloseName); > + EXPECT_EQ(Expected.SelfClosing, Actual.SelfClosing); > + EXPECT_EQ(Expected.Explicit, Actual.Explicit); > + > + ASSERT_EQ(Expected.AttrKeys.size(), Actual.AttrKeys.size()); > + for (size_t Idx = 0; Idx < Actual.AttrKeys.size(); ++Idx) > + EXPECT_EQ(Expected.AttrKeys[Idx], Actual.AttrKeys[Idx]); > + > + ASSERT_EQ(Expected.AttrValues.size(), Actual.AttrValues.size()); > + for (size_t Idx = 0; Idx < Actual.AttrValues.size(); ++Idx) > + EXPECT_EQ(Expected.AttrValues[Idx], Actual.AttrValues[Idx]); > + > + ASSERT_EQ(Expected.Args.size(), Actual.Args.size()); > + for (size_t Idx = 0; Idx < Actual.Args.size(); ++Idx) > + EXPECT_EQ(Expected.Args[Idx], Actual.Args[Idx]); > + > + ASSERT_EQ(Expected.Children.size(), Actual.Children.size()); > + for (size_t Idx = 0; Idx < Actual.Children.size(); ++Idx) > + CheckCommentInfo(*Expected.Children[Idx], *Actual.Children[Idx]); > +} > + > +void CheckReference(Reference &Expected, Reference &Actual) { > + EXPECT_EQ(Expected.Name, Actual.Name); > + EXPECT_EQ(Expected.RefType, Actual.RefType); > +} > + > +void CheckTypeInfo(TypeInfo *Expected, TypeInfo *Actual) { > + CheckReference(Expected->Type, Actual->Type); > +} > + > +void CheckFieldTypeInfo(FieldTypeInfo *Expected, FieldTypeInfo *Actual) { > + CheckTypeInfo(Expected, Actual); > + EXPECT_EQ(Expected->Name, Actual->Name); > +} > + > +void CheckMemberTypeInfo(MemberTypeInfo *Expected, MemberTypeInfo *Actual) { > + CheckFieldTypeInfo(Expected, Actual); > + EXPECT_EQ(Expected->Access, Actual->Access); > +} > + > +void CheckBaseInfo(Info *Expected, Info *Actual) { > + EXPECT_EQ(size_t(20), Actual->USR.size()); > + EXPECT_EQ(Expected->Name, Actual->Name); > + ASSERT_EQ(Expected->Namespace.size(), Actual->Namespace.size()); > + for (size_t Idx = 0; Idx < Actual->Namespace.size(); ++Idx) > + CheckReference(Expected->Namespace[Idx], Actual->Namespace[Idx]); > + ASSERT_EQ(Expected->Description.size(), Actual->Description.size()); > + for (size_t Idx = 0; Idx < Actual->Description.size(); ++Idx) > + CheckCommentInfo(Expected->Description[Idx], Actual->Description[Idx]); > +} > + > +void CheckSymbolInfo(SymbolInfo *Expected, SymbolInfo *Actual) { > + CheckBaseInfo(Expected, Actual); > + EXPECT_EQ(Expected->DefLoc.hasValue(), Actual->DefLoc.hasValue()); > + if (Expected->DefLoc.hasValue() && Actual->DefLoc.hasValue()) { > + EXPECT_EQ(Expected->DefLoc->LineNumber, Actual->DefLoc->LineNumber); > + EXPECT_EQ(Expected->DefLoc->Filename, Actual->DefLoc->Filename); > + } > + ASSERT_EQ(Expected->Loc.size(), Actual->Loc.size()); > + for (size_t Idx = 0; Idx < Actual->Loc.size(); ++Idx) > + EXPECT_EQ(Expected->Loc[Idx], Actual->Loc[Idx]); > +} > + > +void CheckFunctionInfo(FunctionInfo *Expected, FunctionInfo *Actual) { > + CheckSymbolInfo(Expected, Actual); > + > + EXPECT_EQ(Expected->IsMethod, Actual->IsMethod); > + CheckReference(Expected->Parent, Actual->Parent); > + CheckTypeInfo(&Expected->ReturnType, &Actual->ReturnType); > + > + ASSERT_EQ(Expected->Params.size(), Actual->Params.size()); > + for (size_t Idx = 0; Idx < Actual->Params.size(); ++Idx) > + EXPECT_EQ(Expected->Params[Idx], Actual->Params[Idx]); > + > + EXPECT_EQ(Expected->Access, Actual->Access); > +} > + > +void CheckEnumInfo(EnumInfo *Expected, EnumInfo *Actual) { > + CheckSymbolInfo(Expected, Actual); > + > + EXPECT_EQ(Expected->Scoped, Actual->Scoped); > + ASSERT_EQ(Expected->Members.size(), Actual->Members.size()); > + for (size_t Idx = 0; Idx < Actual->Members.size(); ++Idx) > + EXPECT_EQ(Expected->Members[Idx], Actual->Members[Idx]); > +} > + > +void CheckNamespaceInfo(NamespaceInfo *Expected, NamespaceInfo *Actual) { > + CheckBaseInfo(Expected, Actual); > + > + ASSERT_EQ(Expected->ChildNamespaces.size(), > Actual->ChildNamespaces.size()); > + for (size_t Idx = 0; Idx < Actual->ChildNamespaces.size(); ++Idx) > + EXPECT_EQ(Expected->ChildNamespaces[Idx], Actual->ChildNamespaces[Idx]); > + > + ASSERT_EQ(Expected->ChildRecords.size(), Actual->ChildRecords.size()); > + for (size_t Idx = 0; Idx < Actual->ChildRecords.size(); ++Idx) > + EXPECT_EQ(Expected->ChildRecords[Idx], Actual->ChildRecords[Idx]); > + > + ASSERT_EQ(Expected->ChildFunctions.size(), Actual->ChildFunctions.size()); > + for (size_t Idx = 0; Idx < Actual->ChildFunctions.size(); ++Idx) > + CheckFunctionInfo(&Expected->ChildFunctions[Idx], > + &Actual->ChildFunctions[Idx]); > + > + ASSERT_EQ(Expected->ChildEnums.size(), Actual->ChildEnums.size()); > + for (size_t Idx = 0; Idx < Actual->ChildEnums.size(); ++Idx) > + CheckEnumInfo(&Expected->ChildEnums[Idx], &Actual->ChildEnums[Idx]); > +} > + > +void CheckRecordInfo(RecordInfo *Expected, RecordInfo *Actual) { > + CheckSymbolInfo(Expected, Actual); > + > + EXPECT_EQ(Expected->TagType, Actual->TagType); > + > + ASSERT_EQ(Expected->Members.size(), Actual->Members.size()); > + for (size_t Idx = 0; Idx < Actual->Members.size(); ++Idx) > + EXPECT_EQ(Expected->Members[Idx], Actual->Members[Idx]); > + > + ASSERT_EQ(Expected->Parents.size(), Actual->Parents.size()); > + for (size_t Idx = 0; Idx < Actual->Parents.size(); ++Idx) > + CheckReference(Expected->Parents[Idx], Actual->Parents[Idx]); > + > + ASSERT_EQ(Expected->VirtualParents.size(), Actual->VirtualParents.size()); > + for (size_t Idx = 0; Idx < Actual->VirtualParents.size(); ++Idx) > + CheckReference(Expected->VirtualParents[Idx], > Actual->VirtualParents[Idx]); > + > + ASSERT_EQ(Expected->ChildRecords.size(), Actual->ChildRecords.size()); > + for (size_t Idx = 0; Idx < Actual->ChildRecords.size(); ++Idx) > + EXPECT_EQ(Expected->ChildRecords[Idx], Actual->ChildRecords[Idx]); > + > + ASSERT_EQ(Expected->ChildFunctions.size(), Actual->ChildFunctions.size()); > + for (size_t Idx = 0; Idx < Actual->ChildFunctions.size(); ++Idx) > + CheckFunctionInfo(&Expected->ChildFunctions[Idx], > + &Actual->ChildFunctions[Idx]); > + > + ASSERT_EQ(Expected->ChildEnums.size(), Actual->ChildEnums.size()); > + for (size_t Idx = 0; Idx < Actual->ChildEnums.size(); ++Idx) > + CheckEnumInfo(&Expected->ChildEnums[Idx], &Actual->ChildEnums[Idx]); > +} > + > +} // namespace doc > +} // namespace clang > > Added: clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.h > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.h?rev=344650&view=auto > ============================================================================== > --- clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.h (added) > +++ clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.h Tue Oct 16 > 16:06:42 2018 > @@ -0,0 +1,51 @@ > +//===-- clang-doc/ClangDocTest.h > ------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANG_DOC_CLANGDOCTEST_H > +#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANG_DOC_CLANGDOCTEST_H > + > +#include "ClangDocTest.h" > +#include "Representation.h" > +#include "clang/AST/RecursiveASTVisitor.h" > +#include "gtest/gtest.h" > + > +namespace clang { > +namespace doc { > + > +using EmittedInfoList = std::vector<std::unique_ptr<Info>>; > + > +static const SymbolID EmptySID = SymbolID(); > +static const SymbolID NonEmptySID = > + SymbolID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; > + > +NamespaceInfo *InfoAsNamespace(Info *I); > +RecordInfo *InfoAsRecord(Info *I); > +FunctionInfo *InfoAsFunction(Info *I); > +EnumInfo *InfoAsEnum(Info *I); > + > +// Unlike the operator==, these functions explicitly does not check USRs, as > +// that may change and it would be better to not rely on its implementation. > +void CheckReference(Reference &Expected, Reference &Actual); > +void CheckTypeInfo(TypeInfo *Expected, TypeInfo *Actual); > +void CheckFieldTypeInfo(FieldTypeInfo *Expected, FieldTypeInfo *Actual); > +void CheckMemberTypeInfo(MemberTypeInfo *Expected, MemberTypeInfo *Actual); > + > +// This function explicitly does not check USRs, as that may change and it > would > +// be better to not rely on its implementation. > +void CheckBaseInfo(Info *Expected, Info *Actual); > +void CheckSymbolInfo(SymbolInfo *Expected, SymbolInfo *Actual); > +void CheckFunctionInfo(FunctionInfo *Expected, FunctionInfo *Actual); > +void CheckEnumInfo(EnumInfo *Expected, EnumInfo *Actual); > +void CheckNamespaceInfo(NamespaceInfo *Expected, NamespaceInfo *Actual); > +void CheckRecordInfo(RecordInfo *Expected, RecordInfo *Actual); > + > +} // namespace doc > +} // namespace clang > + > +#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANG_DOC_CLANGDOCTEST_H > > Added: clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp?rev=344650&view=auto > ============================================================================== > --- clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp (added) > +++ clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp Tue Oct 16 > 16:06:42 2018 > @@ -0,0 +1,346 @@ > +//===-- clang-doc/SerializeTest.cpp > ---------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "Serialize.h" > +#include "ClangDocTest.h" > +#include "Representation.h" > +#include "clang/AST/Comment.h" > +#include "clang/AST/RecursiveASTVisitor.h" > +#include "gtest/gtest.h" > + > +namespace clang { > +namespace doc { > + > +class ClangDocSerializeTestVisitor > + : public RecursiveASTVisitor<ClangDocSerializeTestVisitor> { > + > + EmittedInfoList &EmittedInfos; > + bool Public; > + > + comments::FullComment *getComment(const NamedDecl *D) const { > + if (RawComment *Comment = > + D->getASTContext().getRawCommentForDeclNoCache(D)) { > + Comment->setAttached(); > + return Comment->parse(D->getASTContext(), nullptr, D); > + } > + return nullptr; > + } > + > +public: > + ClangDocSerializeTestVisitor(EmittedInfoList &EmittedInfos, bool Public) > + : EmittedInfos(EmittedInfos), Public(Public) {} > + > + bool VisitNamespaceDecl(const NamespaceDecl *D) { > + auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, > + /*File=*/"test.cpp", Public); > + if (I) > + EmittedInfos.emplace_back(std::move(I)); > + return true; > + } > + > + bool VisitFunctionDecl(const FunctionDecl *D) { > + // Don't visit CXXMethodDecls twice > + if (dyn_cast<CXXMethodDecl>(D)) > + return true; > + auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, > + /*File=*/"test.cpp", Public); > + if (I) > + EmittedInfos.emplace_back(std::move(I)); > + return true; > + } > + > + bool VisitCXXMethodDecl(const CXXMethodDecl *D) { > + auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, > + /*File=*/"test.cpp", Public); > + if (I) > + EmittedInfos.emplace_back(std::move(I)); > + return true; > + } > + > + bool VisitRecordDecl(const RecordDecl *D) { > + auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, > + /*File=*/"test.cpp", Public); > + if (I) > + EmittedInfos.emplace_back(std::move(I)); > + return true; > + } > + > + bool VisitEnumDecl(const EnumDecl *D) { > + auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, > + /*File=*/"test.cpp", Public); > + if (I) > + EmittedInfos.emplace_back(std::move(I)); > + return true; > + } > +}; > + > +void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool > Public, > + EmittedInfoList &EmittedInfos) { > + auto ASTUnit = clang::tooling::buildASTFromCode(Code); > + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); > + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); > + Visitor.TraverseTranslationUnitDecl(TU); > + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); > +} > + > +void ExtractInfosFromCodeWithArgs(StringRef Code, size_t NumExpectedInfos, > + bool Public, EmittedInfoList &EmittedInfos, > + std::vector<std::string> &Args) { > + auto ASTUnit = clang::tooling::buildASTFromCodeWithArgs(Code, Args); > + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); > + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); > + Visitor.TraverseTranslationUnitDecl(TU); > + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); > +} > + > +// Test serialization of namespace declarations. > +TEST(SerializeTest, emitNamespaceInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 3, > + /*Public=*/false, Infos); > + > + NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedA(EmptySID, "A"); > + CheckNamespaceInfo(&ExpectedA, A); > + > + NamespaceInfo *B = InfoAsNamespace(Infos[1].get()); > + NamespaceInfo ExpectedB(EmptySID, "B"); > + ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); > + CheckNamespaceInfo(&ExpectedB, B); > + > + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[2].get()); > + NamespaceInfo ExpectedBWithFunction(EmptySID); > + FunctionInfo F; > + F.Name = "f"; > + F.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); > + F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace); > + F.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); > + ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F)); > + CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); > +} > + > +TEST(SerializeTest, emitAnonymousNamespaceInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("namespace { }", 1, /*Public=*/false, Infos); > + > + NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedA(EmptySID); > + CheckNamespaceInfo(&ExpectedA, A); > +} > + > +// Test serialization of record declarations. > +TEST(SerializeTest, emitRecordInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode(R"raw(class E { > +public: > + E() {} > +protected: > + void ProtectedMethod(); > +};)raw", 3, /*Public=*/false, Infos); > + > + RecordInfo *E = InfoAsRecord(Infos[0].get()); > + RecordInfo ExpectedE(EmptySID, "E"); > + ExpectedE.TagType = TagTypeKind::TTK_Class; > + ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + CheckRecordInfo(&ExpectedE, E); > + > + RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[1].get()); > + RecordInfo ExpectedRecordWithEConstructor(EmptySID); > + FunctionInfo EConstructor; > + EConstructor.Name = "E"; > + EConstructor.Parent = Reference(EmptySID, "E", InfoType::IT_record); > + EConstructor.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); > + EConstructor.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + EConstructor.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); > + EConstructor.Access = AccessSpecifier::AS_public; > + EConstructor.IsMethod = true; > + ExpectedRecordWithEConstructor.ChildFunctions.emplace_back( > + std::move(EConstructor)); > + CheckRecordInfo(&ExpectedRecordWithEConstructor, RecordWithEConstructor); > + > + RecordInfo *RecordWithMethod = InfoAsRecord(Infos[2].get()); > + RecordInfo ExpectedRecordWithMethod(EmptySID); > + FunctionInfo Method; > + Method.Name = "ProtectedMethod"; > + Method.Parent = Reference(EmptySID, "E", InfoType::IT_record); > + Method.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); > + Method.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); > + Method.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); > + Method.Access = AccessSpecifier::AS_protected; > + Method.IsMethod = true; > + ExpectedRecordWithMethod.ChildFunctions.emplace_back(std::move(Method)); > + CheckRecordInfo(&ExpectedRecordWithMethod, RecordWithMethod); > +} > + > +// Test serialization of enum declarations. > +TEST(SerializeTest, emitEnumInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("enum E { X, Y }; enum class G { A, B };", 2, > + /*Public=*/false, Infos); > + > + NamespaceInfo *NamespaceWithEnum = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedNamespaceWithEnum(EmptySID); > + EnumInfo E; > + E.Name = "E"; > + E.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + E.Members.emplace_back("X"); > + E.Members.emplace_back("Y"); > + ExpectedNamespaceWithEnum.ChildEnums.emplace_back(std::move(E)); > + CheckNamespaceInfo(&ExpectedNamespaceWithEnum, NamespaceWithEnum); > + > + NamespaceInfo *NamespaceWithScopedEnum = InfoAsNamespace(Infos[1].get()); > + NamespaceInfo ExpectedNamespaceWithScopedEnum(EmptySID); > + EnumInfo G; > + G.Name = "G"; > + G.Scoped = true; > + G.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + G.Members.emplace_back("A"); > + G.Members.emplace_back("B"); > + ExpectedNamespaceWithScopedEnum.ChildEnums.emplace_back(std::move(G)); > + CheckNamespaceInfo(&ExpectedNamespaceWithScopedEnum, > NamespaceWithScopedEnum); > +} > + > +TEST(SerializeTest, emitUndefinedRecordInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("class E;", 1, /*Public=*/false, Infos); > + > + RecordInfo *E = InfoAsRecord(Infos[0].get()); > + RecordInfo ExpectedE(EmptySID, "E"); > + ExpectedE.TagType = TagTypeKind::TTK_Class; > + ExpectedE.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); > + CheckRecordInfo(&ExpectedE, E); > +} > + > +TEST(SerializeTest, emitRecordMemberInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("struct E { int I; };", 1, /*Public=*/false, Infos); > + > + RecordInfo *E = InfoAsRecord(Infos[0].get()); > + RecordInfo ExpectedE(EmptySID, "E"); > + ExpectedE.TagType = TagTypeKind::TTK_Struct; > + ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + ExpectedE.Members.emplace_back("int", "I", AccessSpecifier::AS_public); > + CheckRecordInfo(&ExpectedE, E); > +} > + > +TEST(SerializeTest, emitInternalRecordInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("class E { class G {}; };", 2, /*Public=*/false, > Infos); > + > + RecordInfo *E = InfoAsRecord(Infos[0].get()); > + RecordInfo ExpectedE(EmptySID, "E"); > + ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + ExpectedE.TagType = TagTypeKind::TTK_Class; > + CheckRecordInfo(&ExpectedE, E); > + > + RecordInfo *G = InfoAsRecord(Infos[1].get()); > + RecordInfo ExpectedG(EmptySID, "G"); > + ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + ExpectedG.TagType = TagTypeKind::TTK_Class; > + ExpectedG.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record); > + CheckRecordInfo(&ExpectedG, G); > +} > + > +TEST(SerializeTest, emitPublicAnonymousNamespaceInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("namespace { class A; }", 0, /*Public=*/true, Infos); > +} > + > +TEST(SerializeTest, emitPublicFunctionInternalInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("int F() { class G {}; return 0; };", 1, > /*Public=*/true, > + Infos); > + > + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedBWithFunction(EmptySID); > + FunctionInfo F; > + F.Name = "F"; > + F.ReturnType = TypeInfo(EmptySID, "int", InfoType::IT_default); > + F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F)); > + CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); > +} > + > +TEST(SerializeTest, emitInlinedFunctionInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode("inline void F(int I) { };", 1, /*Public=*/true, > Infos); > + > + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedBWithFunction(EmptySID); > + FunctionInfo F; > + F.Name = "F"; > + F.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); > + F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + F.Params.emplace_back("int", "I"); > + ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F)); > + CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); > +} > + > +TEST(SerializeTest, emitInheritedRecordInfo) { > + EmittedInfoList Infos; > + ExtractInfosFromCode( > + "class F {}; class G{} ; class E : public F, virtual private G {};", 3, > + /*Public=*/false, Infos); > + > + RecordInfo *F = InfoAsRecord(Infos[0].get()); > + RecordInfo ExpectedF(EmptySID, "F"); > + ExpectedF.TagType = TagTypeKind::TTK_Class; > + ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + CheckRecordInfo(&ExpectedF, F); > + > + RecordInfo *G = InfoAsRecord(Infos[1].get()); > + RecordInfo ExpectedG(EmptySID, "G"); > + ExpectedG.TagType = TagTypeKind::TTK_Class; > + ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + CheckRecordInfo(&ExpectedG, G); > + > + RecordInfo *E = InfoAsRecord(Infos[2].get()); > + RecordInfo ExpectedE(EmptySID, "E"); > + ExpectedE.Parents.emplace_back(EmptySID, "F", InfoType::IT_record); > + ExpectedE.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record); > + ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"}); > + ExpectedE.TagType = TagTypeKind::TTK_Class; > + CheckRecordInfo(&ExpectedE, E); > +} > + > +TEST(SerializeTest, emitModulePublicLFunctions) { > + EmittedInfoList Infos; > + std::vector<std::string> Args; > + Args.push_back("-fmodules-ts"); > + ExtractInfosFromCodeWithArgs(R"raw(export module M; > +int moduleFunction(int x); > +static int staticModuleFunction(int x); > +export double exportedModuleFunction(double y);)raw", > + 2, /*Public=*/true, Infos, Args); > + > + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get()); > + NamespaceInfo ExpectedBWithFunction(EmptySID); > + FunctionInfo F; > + F.Name = "moduleFunction"; > + F.ReturnType = TypeInfo(EmptySID, "int", InfoType::IT_default); > + F.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); > + F.Params.emplace_back("int", "x"); > + ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F)); > + CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction); > + > + NamespaceInfo *BWithExportedFunction = InfoAsNamespace(Infos[1].get()); > + NamespaceInfo ExpectedBWithExportedFunction(EmptySID); > + FunctionInfo ExportedF; > + ExportedF.Name = "exportedModuleFunction"; > + ExportedF.ReturnType = TypeInfo(EmptySID, "double", InfoType::IT_default); > + ExportedF.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"}); > + ExportedF.Params.emplace_back("double", "y"); > + ExpectedBWithExportedFunction.ChildFunctions.emplace_back( > + std::move(ExportedF)); > + CheckNamespaceInfo(&ExpectedBWithExportedFunction, BWithExportedFunction); > +} > + > +} // namespace doc > +} // end namespace clang > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits