[clang-tools-extra] r364963 - [clang-doc] Serialize child namespaces and records
Julie Hockett via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 2 12:59:56 PDT 2019
Author: juliehockett
Date: Tue Jul 2 12:59:56 2019
New Revision: 364963
URL: http://llvm.org/viewvc/llvm-project?rev=364963&view=rev
Log:
[clang-doc] Serialize child namespaces and records
Serialization of child namespaces and records is now handled.
Namespaces can have child records and child namespaces.
Records can only have child records.
Committed on behalf of Diego Astiazarán (diegoaat97 at gmail.com).
Differential Revision: https://reviews.llvm.org/D63911
Modified:
clang-tools-extra/trunk/clang-doc/Mapper.cpp
clang-tools-extra/trunk/clang-doc/Serialize.cpp
clang-tools-extra/trunk/clang-doc/Serialize.h
clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp
clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp
Modified: clang-tools-extra/trunk/clang-doc/Mapper.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Mapper.cpp?rev=364963&r1=364962&r2=364963&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/Mapper.cpp (original)
+++ clang-tools-extra/trunk/clang-doc/Mapper.cpp Tue Jul 2 12:59:56 2019
@@ -43,9 +43,12 @@ template <typename T> bool MapASTVisitor
// A null in place of I indicates that the serializer is skipping this decl
// for some reason (e.g. we're only reporting public decls).
- if (I)
- CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(I->USR)),
- serialize::serialize(I));
+ if (I.first)
+ CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(I.first->USR)),
+ serialize::serialize(I.first));
+ if (I.second)
+ CDCtx.ECtx->reportResult(llvm::toHex(llvm::toStringRef(I.second->USR)),
+ serialize::serialize(I.second));
return true;
}
Modified: clang-tools-extra/trunk/clang-doc/Serialize.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Serialize.cpp?rev=364963&r1=364962&r2=364963&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/Serialize.cpp (original)
+++ clang-tools-extra/trunk/clang-doc/Serialize.cpp Tue Jul 2 12:59:56 2019
@@ -335,30 +335,39 @@ static void populateFunctionInfo(Functio
parseParameters(I, D);
}
-std::unique_ptr<Info> emitInfo(const NamespaceDecl *D, const FullComment *FC,
- int LineNumber, llvm::StringRef File,
- bool PublicOnly) {
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool PublicOnly) {
auto I = llvm::make_unique<NamespaceInfo>();
bool IsInAnonymousNamespace = false;
populateInfo(*I, D, FC, IsInAnonymousNamespace);
if (PublicOnly && ((IsInAnonymousNamespace || D->isAnonymousNamespace()) ||
!isPublic(D->getAccess(), D->getLinkageInternal())))
- return nullptr;
+ return {};
I->Name = D->isAnonymousNamespace()
? llvm::SmallString<16>("@nonymous_namespace")
: I->Name;
- return std::unique_ptr<Info>{std::move(I)};
+ if (I->Namespace.empty() && I->USR == SymbolID())
+ return {std::unique_ptr<Info>{std::move(I)}, nullptr};
+
+ SymbolID ParentUSR = I->Namespace.empty() ? SymbolID() : I->Namespace[0].USR;
+
+ auto Parent = llvm::make_unique<NamespaceInfo>();
+ Parent->USR = ParentUSR;
+ Parent->ChildNamespaces.emplace_back(I->USR, I->Name, InfoType::IT_namespace);
+ return {std::unique_ptr<Info>{std::move(I)},
+ std::unique_ptr<Info>{std::move(Parent)}};
}
-std::unique_ptr<Info> emitInfo(const RecordDecl *D, const FullComment *FC,
- int LineNumber, llvm::StringRef File,
- bool PublicOnly) {
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool PublicOnly) {
auto I = llvm::make_unique<RecordInfo>();
bool IsInAnonymousNamespace = false;
populateSymbolInfo(*I, D, FC, LineNumber, File, IsInAnonymousNamespace);
if (PublicOnly && ((IsInAnonymousNamespace ||
!isPublic(D->getAccess(), D->getLinkageInternal()))))
- return nullptr;
+ return {};
I->TagType = D->getTagKind();
parseFields(*I, D, PublicOnly);
@@ -369,18 +378,44 @@ std::unique_ptr<Info> emitInfo(const Rec
}
parseBases(*I, C);
}
- return std::unique_ptr<Info>{std::move(I)};
+
+ if (I->Namespace.empty()) {
+ auto Parent = llvm::make_unique<NamespaceInfo>();
+ Parent->USR = SymbolID();
+ Parent->ChildRecords.emplace_back(I->USR, I->Name, InfoType::IT_record);
+ return {std::unique_ptr<Info>{std::move(I)},
+ std::unique_ptr<Info>{std::move(Parent)}};
+ }
+
+ switch (I->Namespace[0].RefType) {
+ case InfoType::IT_namespace: {
+ auto Parent = llvm::make_unique<NamespaceInfo>();
+ Parent->USR = I->Namespace[0].USR;
+ Parent->ChildRecords.emplace_back(I->USR, I->Name, InfoType::IT_record);
+ return {std::unique_ptr<Info>{std::move(I)},
+ std::unique_ptr<Info>{std::move(Parent)}};
+ }
+ case InfoType::IT_record: {
+ auto Parent = llvm::make_unique<RecordInfo>();
+ Parent->USR = I->Namespace[0].USR;
+ Parent->ChildRecords.emplace_back(I->USR, I->Name, InfoType::IT_record);
+ return {std::unique_ptr<Info>{std::move(I)},
+ std::unique_ptr<Info>{std::move(Parent)}};
+ }
+ default:
+ llvm_unreachable("Invalid reference type");
+ }
}
-std::unique_ptr<Info> emitInfo(const FunctionDecl *D, const FullComment *FC,
- int LineNumber, llvm::StringRef File,
- bool PublicOnly) {
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, LineNumber, File, IsInAnonymousNamespace);
if (PublicOnly && ((IsInAnonymousNamespace ||
!isPublic(D->getAccess(), D->getLinkageInternal()))))
- return nullptr;
+ return {};
Func.Access = clang::AccessSpecifier::AS_none;
@@ -391,18 +426,19 @@ std::unique_ptr<Info> emitInfo(const Fun
else
I->USR = SymbolID();
I->ChildFunctions.emplace_back(std::move(Func));
- return std::unique_ptr<Info>{std::move(I)};
+ // Info es wrapped in its parent scope so it's returned in the second position
+ return {nullptr, std::unique_ptr<Info>{std::move(I)}};
}
-std::unique_ptr<Info> emitInfo(const CXXMethodDecl *D, const FullComment *FC,
- int LineNumber, llvm::StringRef File,
- bool PublicOnly) {
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, LineNumber, File, IsInAnonymousNamespace);
if (PublicOnly && ((IsInAnonymousNamespace ||
!isPublic(D->getAccess(), D->getLinkageInternal()))))
- return nullptr;
+ return {};
Func.IsMethod = true;
@@ -422,18 +458,19 @@ std::unique_ptr<Info> emitInfo(const CXX
auto I = llvm::make_unique<RecordInfo>();
I->USR = ParentUSR;
I->ChildFunctions.emplace_back(std::move(Func));
- return std::unique_ptr<Info>{std::move(I)};
+ // Info is wrapped in its parent scope so it's returned in the second position
+ return {nullptr, std::unique_ptr<Info>{std::move(I)}};
}
-std::unique_ptr<Info> emitInfo(const EnumDecl *D, const FullComment *FC,
- int LineNumber, llvm::StringRef File,
- bool PublicOnly) {
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
+ llvm::StringRef File, bool PublicOnly) {
EnumInfo Enum;
bool IsInAnonymousNamespace = false;
populateSymbolInfo(Enum, D, FC, LineNumber, File, IsInAnonymousNamespace);
if (PublicOnly && ((IsInAnonymousNamespace ||
!isPublic(D->getAccess(), D->getLinkageInternal()))))
- return nullptr;
+ return {};
Enum.Scoped = D->isScoped();
parseEnumerators(Enum, D);
@@ -445,13 +482,17 @@ std::unique_ptr<Info> emitInfo(const Enu
auto I = llvm::make_unique<NamespaceInfo>();
I->USR = Enum.Namespace[0].USR;
I->ChildEnums.emplace_back(std::move(Enum));
- return std::unique_ptr<Info>{std::move(I)};
+ // Info is wrapped in its parent scope so it's returned in the second
+ // position
+ return {nullptr, std::unique_ptr<Info>{std::move(I)}};
}
case InfoType::IT_record: {
auto I = llvm::make_unique<RecordInfo>();
I->USR = Enum.Namespace[0].USR;
I->ChildEnums.emplace_back(std::move(Enum));
- return std::unique_ptr<Info>{std::move(I)};
+ // Info is wrapped in its parent scope so it's returned in the second
+ // position
+ return {nullptr, std::unique_ptr<Info>{std::move(I)}};
}
default:
break;
@@ -462,7 +503,8 @@ std::unique_ptr<Info> emitInfo(const Enu
auto I = llvm::make_unique<NamespaceInfo>();
I->USR = SymbolID();
I->ChildEnums.emplace_back(std::move(Enum));
- return std::unique_ptr<Info>{std::move(I)};
+ // Info is wrapped in its parent scope so it's returned in the second position
+ return {nullptr, std::unique_ptr<Info>{std::move(I)}};
}
} // namespace serialize
Modified: clang-tools-extra/trunk/clang-doc/Serialize.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Serialize.h?rev=364963&r1=364962&r2=364963&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/Serialize.h (original)
+++ clang-tools-extra/trunk/clang-doc/Serialize.h Tue Jul 2 12:59:56 2019
@@ -27,16 +27,30 @@ namespace clang {
namespace doc {
namespace serialize {
-std::unique_ptr<Info> emitInfo(const NamespaceDecl *D, const FullComment *FC,
- int LineNumber, StringRef File, bool PublicOnly);
-std::unique_ptr<Info> emitInfo(const RecordDecl *D, const FullComment *FC,
- int LineNumber, StringRef File, bool PublicOnly);
-std::unique_ptr<Info> emitInfo(const EnumDecl *D, const FullComment *FC,
- int LineNumber, StringRef File, bool PublicOnly);
-std::unique_ptr<Info> emitInfo(const FunctionDecl *D, const FullComment *FC,
- int LineNumber, StringRef File, bool PublicOnly);
-std::unique_ptr<Info> emitInfo(const CXXMethodDecl *D, const FullComment *FC,
- int LineNumber, StringRef File, bool PublicOnly);
+// The first element will contain the relevant information about the declaration
+// passed as parameter.
+// The second element will contain the relevant information about the
+// declaration's parent, it can be a NamespaceInfo or RecordInfo.
+// Both elements can be nullptrs if the declaration shouldn't be handled.
+// When the declaration is handled, the first element will be a nullptr for
+// EnumDecl, FunctionDecl and CXXMethodDecl; they are only returned wrapped in
+// its parent scope. For NamespaceDecl and RecordDecl both elements are not
+// nullptr.
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool PublicOnly);
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool PublicOnly);
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool PublicOnly);
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool PublicOnly);
+std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
+ StringRef File, bool PublicOnly);
// Function to hash a given USR value for storage.
// As USRs (Unified Symbol Resolution) could be large, especially for functions
Modified: 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=364963&r1=364962&r2=364963&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-doc/ClangDocTest.cpp Tue Jul 2 12:59:56 2019
@@ -130,11 +130,12 @@ void CheckNamespaceInfo(NamespaceInfo *E
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]);
+ CheckReference(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]);
+ CheckReference(Expected->ChildRecords[Idx], Actual->ChildRecords[Idx]);
ASSERT_EQ(Expected->ChildFunctions.size(), Actual->ChildFunctions.size());
for (size_t Idx = 0; Idx < Actual->ChildFunctions.size(); ++Idx)
@@ -167,7 +168,7 @@ void CheckRecordInfo(RecordInfo *Expecte
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]);
+ CheckReference(Expected->ChildRecords[Idx], Actual->ChildRecords[Idx]);
ASSERT_EQ(Expected->ChildFunctions.size(), Actual->ChildFunctions.size());
for (size_t Idx = 0; Idx < Actual->ChildFunctions.size(); ++Idx)
Modified: 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=364963&r1=364962&r2=364963&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-doc/SerializeTest.cpp Tue Jul 2 12:59:56 2019
@@ -35,48 +35,30 @@ public:
ClangDocSerializeTestVisitor(EmittedInfoList &EmittedInfos, bool Public)
: EmittedInfos(EmittedInfos), Public(Public) {}
- bool VisitNamespaceDecl(const NamespaceDecl *D) {
+ template <typename T> bool mapDecl(const T *D) {
auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0,
/*File=*/"test.cpp", Public);
- if (I)
- EmittedInfos.emplace_back(std::move(I));
+ if (I.first)
+ EmittedInfos.emplace_back(std::move(I.first));
+ if (I.second)
+ EmittedInfos.emplace_back(std::move(I.second));
return true;
}
+ bool VisitNamespaceDecl(const NamespaceDecl *D) { return mapDecl(D); }
+
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;
+ return mapDecl(D);
}
- 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 VisitCXXMethodDecl(const CXXMethodDecl *D) { return mapDecl(D); }
- 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 VisitRecordDecl(const RecordDecl *D) { return mapDecl(D); }
- 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;
- }
+ bool VisitEnumDecl(const EnumDecl *D) { return mapDecl(D); }
};
void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool Public,
@@ -101,19 +83,19 @@ void ExtractInfosFromCodeWithArgs(String
// Test serialization of namespace declarations.
TEST(SerializeTest, emitNamespaceInfo) {
EmittedInfoList Infos;
- ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 3,
+ ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 5,
/*Public=*/false, Infos);
NamespaceInfo *A = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedA(EmptySID, "A");
CheckNamespaceInfo(&ExpectedA, A);
- NamespaceInfo *B = InfoAsNamespace(Infos[1].get());
+ NamespaceInfo *B = InfoAsNamespace(Infos[2].get());
NamespaceInfo ExpectedB(EmptySID, "B");
ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
CheckNamespaceInfo(&ExpectedB, B);
- NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[2].get());
+ NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[4].get());
NamespaceInfo ExpectedBWithFunction(EmptySID);
FunctionInfo F;
F.Name = "f";
@@ -127,7 +109,7 @@ TEST(SerializeTest, emitNamespaceInfo) {
TEST(SerializeTest, emitAnonymousNamespaceInfo) {
EmittedInfoList Infos;
- ExtractInfosFromCode("namespace { }", 1, /*Public=*/false, Infos);
+ ExtractInfosFromCode("namespace { }", 2, /*Public=*/false, Infos);
NamespaceInfo *A = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedA(EmptySID);
@@ -151,7 +133,7 @@ struct F {
template <>
void F<int>::TemplateMethod();
typedef struct {} G;)raw",
- 7, /*Public=*/false, Infos);
+ 10, /*Public=*/false, Infos);
RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, "E");
@@ -159,7 +141,7 @@ typedef struct {} G;)raw",
ExpectedE.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[1].get());
+ RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[2].get());
RecordInfo ExpectedRecordWithEConstructor(EmptySID);
FunctionInfo EConstructor;
EConstructor.Name = "E";
@@ -173,7 +155,7 @@ typedef struct {} G;)raw",
std::move(EConstructor));
CheckRecordInfo(&ExpectedRecordWithEConstructor, RecordWithEConstructor);
- RecordInfo *RecordWithMethod = InfoAsRecord(Infos[2].get());
+ RecordInfo *RecordWithMethod = InfoAsRecord(Infos[3].get());
RecordInfo ExpectedRecordWithMethod(EmptySID);
FunctionInfo Method;
Method.Name = "ProtectedMethod";
@@ -186,13 +168,13 @@ typedef struct {} G;)raw",
ExpectedRecordWithMethod.ChildFunctions.emplace_back(std::move(Method));
CheckRecordInfo(&ExpectedRecordWithMethod, RecordWithMethod);
- RecordInfo *F = InfoAsRecord(Infos[3].get());
+ RecordInfo *F = InfoAsRecord(Infos[4].get());
RecordInfo ExpectedF(EmptySID, "F");
ExpectedF.TagType = TagTypeKind::TTK_Struct;
ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
CheckRecordInfo(&ExpectedF, F);
- RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[4].get());
+ RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[6].get());
RecordInfo ExpectedRecordWithTemplateMethod(EmptySID);
FunctionInfo TemplateMethod;
TemplateMethod.Name = "TemplateMethod";
@@ -206,7 +188,7 @@ typedef struct {} G;)raw",
std::move(TemplateMethod));
CheckRecordInfo(&ExpectedRecordWithTemplateMethod, RecordWithTemplateMethod);
- RecordInfo *TemplatedRecord = InfoAsRecord(Infos[5].get());
+ RecordInfo *TemplatedRecord = InfoAsRecord(Infos[7].get());
RecordInfo ExpectedTemplatedRecord(EmptySID);
FunctionInfo SpecializedTemplateMethod;
SpecializedTemplateMethod.Name = "TemplateMethod";
@@ -224,7 +206,7 @@ typedef struct {} G;)raw",
std::move(SpecializedTemplateMethod));
CheckRecordInfo(&ExpectedTemplatedRecord, TemplatedRecord);
- RecordInfo *G = InfoAsRecord(Infos[6].get());
+ RecordInfo *G = InfoAsRecord(Infos[8].get());
RecordInfo ExpectedG(EmptySID, "G");
ExpectedG.TagType = TagTypeKind::TTK_Struct;
ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
@@ -262,7 +244,7 @@ TEST(SerializeTest, emitEnumInfo) {
TEST(SerializeTest, emitUndefinedRecordInfo) {
EmittedInfoList Infos;
- ExtractInfosFromCode("class E;", 1, /*Public=*/false, Infos);
+ ExtractInfosFromCode("class E;", 2, /*Public=*/false, Infos);
RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, "E");
@@ -273,7 +255,7 @@ TEST(SerializeTest, emitUndefinedRecordI
TEST(SerializeTest, emitRecordMemberInfo) {
EmittedInfoList Infos;
- ExtractInfosFromCode("struct E { int I; };", 1, /*Public=*/false, Infos);
+ ExtractInfosFromCode("struct E { int I; };", 2, /*Public=*/false, Infos);
RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, "E");
@@ -285,7 +267,7 @@ TEST(SerializeTest, emitRecordMemberInfo
TEST(SerializeTest, emitInternalRecordInfo) {
EmittedInfoList Infos;
- ExtractInfosFromCode("class E { class G {}; };", 2, /*Public=*/false, Infos);
+ ExtractInfosFromCode("class E { class G {}; };", 4, /*Public=*/false, Infos);
RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, "E");
@@ -293,7 +275,7 @@ TEST(SerializeTest, emitInternalRecordIn
ExpectedE.TagType = TagTypeKind::TTK_Class;
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *G = InfoAsRecord(Infos[1].get());
+ RecordInfo *G = InfoAsRecord(Infos[2].get());
RecordInfo ExpectedG(EmptySID, "G");
ExpectedG.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
ExpectedG.TagType = TagTypeKind::TTK_Class;
@@ -336,7 +318,7 @@ TEST(SerializeTest, emitInlinedFunctionI
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
}
-TEST(SerializeTest, emitInheritedRecordInfo) {
+TEST(SerializeTest, ) {
EmittedInfoList Infos;
ExtractInfosFromCode(R"raw(class F {};
class G {} ;
@@ -344,7 +326,7 @@ class E : public F, virtual private G {}
template <typename T>
class H {} ;
class I : public H<int> {} ;)raw",
- 5, /*Public=*/false, Infos);
+ 10, /*Public=*/false, Infos);
RecordInfo *F = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedF(EmptySID, "F");
@@ -352,13 +334,13 @@ class I : public H<int> {} ;)raw",
ExpectedF.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
CheckRecordInfo(&ExpectedF, F);
- RecordInfo *G = InfoAsRecord(Infos[1].get());
+ RecordInfo *G = InfoAsRecord(Infos[2].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 *E = InfoAsRecord(Infos[4].get());
RecordInfo ExpectedE(EmptySID, "E");
ExpectedE.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
ExpectedE.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
@@ -366,13 +348,13 @@ class I : public H<int> {} ;)raw",
ExpectedE.TagType = TagTypeKind::TTK_Class;
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *H = InfoAsRecord(Infos[3].get());
+ RecordInfo *H = InfoAsRecord(Infos[6].get());
RecordInfo ExpectedH(EmptySID, "H");
ExpectedH.TagType = TagTypeKind::TTK_Class;
ExpectedH.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
CheckRecordInfo(&ExpectedH, H);
- RecordInfo *I = InfoAsRecord(Infos[4].get());
+ RecordInfo *I = InfoAsRecord(Infos[8].get());
RecordInfo ExpectedI(EmptySID, "I");
ExpectedI.Parents.emplace_back(EmptySID, "H<int>", InfoType::IT_record);
ExpectedI.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
@@ -412,5 +394,46 @@ export double exportedModuleFunction(dou
CheckNamespaceInfo(&ExpectedBWithExportedFunction, BWithExportedFunction);
}
+// Test serialization of child records in namespaces and other records
+TEST(SerializeTest, emitChildRecords) {
+ EmittedInfoList Infos;
+ ExtractInfosFromCode("class A { class B {}; }; namespace { class C {}; } ", 8,
+ /*Public=*/false, Infos);
+
+ NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get());
+ NamespaceInfo ExpectedParentA(EmptySID);
+ ExpectedParentA.ChildRecords.emplace_back(EmptySID, "A", InfoType::IT_record);
+ CheckNamespaceInfo(&ExpectedParentA, ParentA);
+
+ RecordInfo *ParentB = InfoAsRecord(Infos[3].get());
+ RecordInfo ExpectedParentB(EmptySID);
+ ExpectedParentB.ChildRecords.emplace_back(EmptySID, "B", InfoType::IT_record);
+ CheckRecordInfo(&ExpectedParentB, ParentB);
+
+ NamespaceInfo *ParentC = InfoAsNamespace(Infos[7].get());
+ NamespaceInfo ExpectedParentC(EmptySID);
+ ExpectedParentC.ChildRecords.emplace_back(EmptySID, "C", InfoType::IT_record);
+ CheckNamespaceInfo(&ExpectedParentC, ParentC);
+}
+
+// Test serialization of child namespaces
+TEST(SerializeTest, emitChildNamespaces) {
+ EmittedInfoList Infos;
+ ExtractInfosFromCode("namespace A { namespace B { } }", 4, /*Public=*/false,
+ Infos);
+
+ NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get());
+ NamespaceInfo ExpectedParentA(EmptySID);
+ ExpectedParentA.ChildNamespaces.emplace_back(EmptySID, "A",
+ InfoType::IT_namespace);
+ CheckNamespaceInfo(&ExpectedParentA, ParentA);
+
+ NamespaceInfo *ParentB = InfoAsNamespace(Infos[3].get());
+ NamespaceInfo ExpectedParentB(EmptySID);
+ ExpectedParentB.ChildNamespaces.emplace_back(EmptySID, "B",
+ InfoType::IT_namespace);
+ CheckNamespaceInfo(&ExpectedParentB, ParentB);
+}
+
} // namespace doc
} // end namespace clang
More information about the cfe-commits
mailing list