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