[clang-tools-extra] 22e6a26 - Revert clang-doc arena merging patches (#191668)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 13 08:40:46 PDT 2026
Author: Paul Kirth
Date: 2026-04-13T15:40:40Z
New Revision: 22e6a261fae1eb57105cc131592026701f283e0e
URL: https://github.com/llvm/llvm-project/commit/22e6a261fae1eb57105cc131592026701f283e0e
DIFF: https://github.com/llvm/llvm-project/commit/22e6a261fae1eb57105cc131592026701f283e0e.diff
LOG: Revert clang-doc arena merging patches (#191668)
This is a set of squashed reverts of recent clang doc patches, since its
breaking something on Darwin builders:
https://lab.llvm.org/buildbot/#/builders/23/builds/19172
Revert "[clang-doc][nfc] Default initialize all StringRef members
(#191641)"
This reverts commit 155b9b354c1d91661be9f6d0432a96e47cfc2700.
Revert "[clang-doc] Initialize StringRef members in Info types
(#191637)"
This reverts commit 489dab3827b255d21ea38b1e3f45ddb08bd10a87.
Revert "[clang-doc] Initialize member variable (#191570)"
This reverts commit 5d64a44a84af31f9e99d42cccffa4f01c0be2e0b.
Revert "[clang-doc] Merge data into persistent memory (#190056)"
This reverts commit 21e0034c69489eff3b09929e5e13ea34b3dd0e5a.
Revert "[clang-doc] Support deep copy between arenas for merging
(#190055)"
This reverts commit c70dae8b0cee46af1411bc4e4ba6fc28e2babf3e.
Added:
Modified:
clang-tools-extra/clang-doc/BitcodeReader.cpp
clang-tools-extra/clang-doc/BitcodeReader.h
clang-tools-extra/clang-doc/JSONGenerator.cpp
clang-tools-extra/clang-doc/MDGenerator.cpp
clang-tools-extra/clang-doc/Mapper.cpp
clang-tools-extra/clang-doc/Representation.cpp
clang-tools-extra/clang-doc/Representation.h
clang-tools-extra/clang-doc/Serialize.cpp
clang-tools-extra/clang-doc/Serialize.h
clang-tools-extra/clang-doc/YAMLGenerator.cpp
clang-tools-extra/clang-doc/benchmarks/ClangDocBenchmark.cpp
clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
clang-tools-extra/unittests/clang-doc/ClangDocTest.h
clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp
clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
clang-tools-extra/unittests/clang-doc/MergeTest.cpp
clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index c5e848ae4c28d..b7f4d6aa7ba23 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -129,15 +129,14 @@ static llvm::Error decodeRecord(const Record &R, FieldId &Field,
"invalid value for FieldId");
}
-static llvm::Error decodeRecord(const Record &R, OwningVec<Location> &Field,
+static llvm::Error decodeRecord(const Record &R,
+ llvm::SmallVectorImpl<Location> &Field,
llvm::StringRef Blob) {
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
-
- Field.push_back(*allocatePtr<Location>(static_cast<int>(R[0]),
- static_cast<int>(R[1]), Blob,
- static_cast<bool>(R[2])));
+ Field.emplace_back(static_cast<int>(R[0]), static_cast<int>(R[1]), Blob,
+ static_cast<bool>(R[2]));
return llvm::Error::success();
}
@@ -426,99 +425,6 @@ ClangDocBitcodeReader::parseBlock(unsigned ID, T I, BlockBeginHandler &&BBH,
}
}
-template <typename T, typename BlockBeginHandler, typename BlockEndHandler>
-llvm::Error ClangDocBitcodeReader::parseBlock(unsigned ID, T I,
- BlockBeginHandler &&BBH,
- BlockEndHandler &&BEH) {
- return parseBlock(ID, I, std::forward<BlockBeginHandler>(BBH),
- std::forward<BlockEndHandler>(BEH),
- [&](unsigned Code) { return readRecord(Code, I); });
-}
-
-template <typename ChildType>
-llvm::Expected<bool> ClangDocBitcodeReader::readSubBlockIfMatch(
- unsigned ID, unsigned TargetID, llvm::SmallVectorImpl<ChildType> &V) {
- if (ID != TargetID)
- return false;
- ChildType Val;
- if (auto Err = readBlock(ID, &Val))
- return std::move(Err);
- V.push_back(std::move(Val));
- return true;
-}
-
-template <typename T>
-static llvm::Error addReference(T I, Reference &&R, FieldId F);
-
-template <> llvm::Error addReference(VarInfo *I, Reference &&R, FieldId F);
-template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F);
-template <>
-llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F);
-template <>
-llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F);
-template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F);
-template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F);
-template <>
-llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F);
-template <> llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F);
-template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F);
-template <>
-llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F);
-template <>
-llvm::Error addReference(FriendInfo *Friend, Reference &&R, FieldId F);
-
-template <typename InfoT>
-llvm::Expected<bool> ClangDocBitcodeReader::routeReferenceBlock(
- unsigned ID, llvm::SmallVectorImpl<Reference> &Namespaces, InfoT *I,
- std::initializer_list<ReferenceMap> Mappings) {
- if (ID != BI_REFERENCE_BLOCK_ID)
- return false;
- Reference R;
- if (auto Err = readBlock(ID, &R))
- return std::move(Err);
-
- for (const auto &Map : Mappings) {
- if (CurrentReferenceField == Map.Field) {
- Map.Vec->push_back(std::move(R));
- return true;
- }
- }
-
- if (CurrentReferenceField == FieldId::F_namespace) {
- Namespaces.push_back(std::move(R));
- return true;
- }
-
- if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
- return std::move(Err);
-
- return true;
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, CommentInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FunctionInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, EnumInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, BaseRecordInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, RecordInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, TemplateInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID,
- TemplateSpecializationInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, VarInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, TypedefInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, NamespaceInfo *I);
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FriendInfo *I);
-
template <>
llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, CommentInfo *I) {
llvm::SmallVector<CommentInfo> LocalChildren;
@@ -542,13 +448,25 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, CommentInfo *I) {
if (!LocalChildren.empty())
I->Children =
allocateArray<CommentInfo>(LocalChildren, TransientArena);
- if (!AttrKeys.empty())
- I->AttrKeys = allocateArray(AttrKeys, TransientArena);
- if (!AttrValues.empty())
- I->AttrValues = allocateArray(AttrValues, TransientArena);
- if (!Args.empty())
- I->Args = allocateArray(Args, TransientArena);
-
+ if (!AttrKeys.empty()) {
+ StringRef *KeysMem =
+ TransientArena.Allocate<StringRef>(AttrKeys.size());
+ std::uninitialized_copy(AttrKeys.begin(), AttrKeys.end(), KeysMem);
+ I->AttrKeys = llvm::ArrayRef<StringRef>(KeysMem, AttrKeys.size());
+ }
+ if (!AttrValues.empty()) {
+ StringRef *ValuesMem =
+ TransientArena.Allocate<StringRef>(AttrValues.size());
+ std::uninitialized_copy(AttrValues.begin(), AttrValues.end(),
+ ValuesMem);
+ I->AttrValues =
+ llvm::ArrayRef<StringRef>(ValuesMem, AttrValues.size());
+ }
+ if (!Args.empty()) {
+ StringRef *ArgsMem = TransientArena.Allocate<StringRef>(Args.size());
+ std::uninitialized_copy(Args.begin(), Args.end(), ArgsMem);
+ I->Args = llvm::ArrayRef<StringRef>(ArgsMem, Args.size());
+ }
return llvm::Error::success();
},
[&](unsigned BlockOrCode) -> llvm::Error {
@@ -563,219 +481,6 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, CommentInfo *I) {
});
}
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FunctionInfo *I) {
- llvm::SmallVector<FieldTypeInfo, 4> LocalParams;
- llvm::SmallVector<Reference> LocalNamespaces;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_FIELD_TYPE_BLOCK_ID,
- LocalParams);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
- return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
- },
- [&]() -> llvm::Error {
- I->Params = allocateArray(LocalParams, TransientArena);
- if (!LocalNamespaces.empty())
- I->Namespace = allocateArray(LocalNamespaces, TransientArena);
- return llvm::Error::success();
- });
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, EnumInfo *I) {
- llvm::SmallVector<EnumValueInfo, 4> LocalMembers;
- llvm::SmallVector<Reference> LocalNamespaces;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_ENUM_VALUE_BLOCK_ID,
- LocalMembers);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
- return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
- },
- [&]() -> llvm::Error {
- I->Members = allocateArray(LocalMembers, TransientArena);
- if (!LocalNamespaces.empty())
- I->Namespace = allocateArray(LocalNamespaces, TransientArena);
- return llvm::Error::success();
- });
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, BaseRecordInfo *I) {
- // BaseRecordInfo and FriendInfo are over 256 bytes and require a size.
- llvm::SmallVector<BaseRecordInfo, 4> LocalBases;
- llvm::SmallVector<FriendInfo, 4> LocalFriends;
- llvm::SmallVector<MemberTypeInfo> LocalMembers;
- llvm::SmallVector<Reference> LocalParents;
- llvm::SmallVector<Reference> LocalVirtualParents;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_MEMBER_TYPE_BLOCK_ID,
- LocalMembers);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- B = readSubBlockIfMatch(BlockOrCode, BI_BASE_RECORD_BLOCK_ID,
- LocalBases);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- B = readSubBlockIfMatch(BlockOrCode, BI_FRIEND_BLOCK_ID, LocalFriends);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- llvm::SmallVector<Reference> Dummy;
- return routeReferenceBlock(
- BlockOrCode, Dummy, I,
- {{FieldId::F_parent, &LocalParents},
- {FieldId::F_vparent, &LocalVirtualParents}});
- },
- [&]() -> llvm::Error {
- if (!LocalMembers.empty())
- I->Members = allocateArray(LocalMembers, TransientArena);
- if (!LocalParents.empty())
- I->Parents = allocateArray(LocalParents, TransientArena);
- if (!LocalVirtualParents.empty())
- I->VirtualParents =
- allocateArray(LocalVirtualParents, TransientArena);
- I->Bases = allocateArray(LocalBases, TransientArena);
- I->Friends = allocateArray(LocalFriends, TransientArena);
- return llvm::Error::success();
- });
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, RecordInfo *I) {
- llvm::SmallVector<BaseRecordInfo, 4> LocalBases;
- llvm::SmallVector<FriendInfo, 4> LocalFriends;
- llvm::SmallVector<MemberTypeInfo> LocalMembers;
- llvm::SmallVector<Reference> LocalParents;
- llvm::SmallVector<Reference> LocalVirtualParents;
- llvm::SmallVector<Reference> LocalNamespaces;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_MEMBER_TYPE_BLOCK_ID,
- LocalMembers);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- B = readSubBlockIfMatch(BlockOrCode, BI_BASE_RECORD_BLOCK_ID,
- LocalBases);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- B = readSubBlockIfMatch(BlockOrCode, BI_FRIEND_BLOCK_ID, LocalFriends);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- return routeReferenceBlock(
- BlockOrCode, LocalNamespaces, I,
- {{FieldId::F_parent, &LocalParents},
- {FieldId::F_vparent, &LocalVirtualParents}});
- },
- [&]() -> llvm::Error {
- if (!LocalMembers.empty())
- I->Members = allocateArray(LocalMembers, TransientArena);
- if (!LocalParents.empty())
- I->Parents = allocateArray(LocalParents, TransientArena);
- if (!LocalVirtualParents.empty())
- I->VirtualParents =
- allocateArray(LocalVirtualParents, TransientArena);
- if (!LocalNamespaces.empty())
- I->Namespace = allocateArray(LocalNamespaces, TransientArena);
- I->Bases = allocateArray(LocalBases, TransientArena);
- I->Friends = allocateArray(LocalFriends, TransientArena);
- return llvm::Error::success();
- });
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, TemplateInfo *I) {
- llvm::SmallVector<TemplateParamInfo> LocalParams;
- llvm::SmallVector<ConstraintInfo> LocalConstraints;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_TEMPLATE_PARAM_BLOCK_ID,
- LocalParams);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- B = readSubBlockIfMatch(BlockOrCode, BI_CONSTRAINT_BLOCK_ID,
- LocalConstraints);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- return false;
- },
- [&]() -> llvm::Error {
- I->Params = allocateArray(LocalParams, TransientArena);
- I->Constraints = allocateArray(LocalConstraints, TransientArena);
- return llvm::Error::success();
- },
- [&](unsigned BlockOrCode) -> llvm::Error {
- return readRecord(BlockOrCode, I);
- });
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID,
- TemplateSpecializationInfo *I) {
- llvm::SmallVector<TemplateParamInfo> LocalParams;
-
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_TEMPLATE_PARAM_BLOCK_ID,
- LocalParams);
- if (!B)
- return B.takeError();
- if (*B)
- return true;
-
- return false;
- },
- [&]() -> llvm::Error {
- I->Params = allocateArray(LocalParams, TransientArena);
- return llvm::Error::success();
- },
- [&](unsigned BlockOrCode) -> llvm::Error {
- return readRecord(BlockOrCode, I);
- });
-}
-
static llvm::Error parseRecord(const Record &R, unsigned ID,
llvm::StringRef Blob, Reference *I, FieldId &F) {
switch (ID) {
@@ -874,25 +579,51 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, StringRef Blob,
"invalid field for Friend");
}
-template <typename, typename = void>
-struct has_description : std::false_type {};
-template <typename T>
-struct has_description<T, std::void_t<decltype(std::declval<T>().Description)>>
- : std::true_type {};
-
template <typename T> static llvm::Expected<CommentInfo *> getCommentInfo(T I) {
- if constexpr (std::is_pointer_v<T>) {
- using Pointee = std::remove_pointer_t<T>;
- if constexpr (has_description<Pointee>::value) {
- auto *NewComment = allocatePtr<CommentInfo>();
- I->Description.push_back(*NewComment);
- return NewComment;
- }
- }
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid type cannot contain CommentInfo");
}
+template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumValueInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> llvm::Expected<CommentInfo *> getCommentInfo(ConceptInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> Expected<CommentInfo *> getCommentInfo(VarInfo *I) {
+ return &I->Description.emplace_back();
+}
+
+template <> Expected<CommentInfo *> getCommentInfo(FriendInfo *I) {
+ return &I->Description.emplace_back();
+}
+
// When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
// the parent block to set it. The template specializations define what to do
// for each supported parent block.
@@ -902,11 +633,26 @@ static llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
"invalid type cannot contain TypeInfo");
}
+template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
+ I->Members.emplace_back(std::move(T));
+ return llvm::Error::success();
+}
+
+template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
+ I->Members.emplace_back(std::move(T));
+ return llvm::Error::success();
+}
+
template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
I->ReturnType = std::move(T);
return llvm::Error::success();
}
+template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
+ I->Params.emplace_back(std::move(T));
+ return llvm::Error::success();
+}
+
template <> llvm::Error addTypeInfo(FriendInfo *I, TypeInfo &&T) {
I->ReturnType.emplace(std::move(T));
return llvm::Error::success();
@@ -935,6 +681,9 @@ static llvm::Error addReference(T I, Reference &&R, FieldId F) {
template <> llvm::Error addReference(VarInfo *I, Reference &&R, FieldId F) {
switch (F) {
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
+ return llvm::Error::success();
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"VarInfo cannot contain this Reference");
@@ -978,6 +727,9 @@ llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) {
template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
switch (F) {
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
+ return llvm::Error::success();
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid type cannot contain Reference");
@@ -986,6 +738,9 @@ template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
switch (F) {
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
+ return llvm::Error::success();
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid type cannot contain Reference");
@@ -995,13 +750,16 @@ template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
template <>
llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
switch (F) {
- case FieldId::F_child_namespace:
- I->Children.Namespaces.push_back(
- *allocatePtr<Reference>(TransientArena, std::move(R)));
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
return llvm::Error::success();
+ case FieldId::F_child_namespace: {
+ Reference *NewR = allocatePtr<Reference>(TransientArena, std::move(R));
+ I->Children.Namespaces.push_back(*NewR);
+ return llvm::Error::success();
+ }
case FieldId::F_child_record:
- I->Children.Records.push_back(
- *allocatePtr<Reference>(TransientArena, std::move(R)));
+ I->Children.Records.emplace_back(std::move(R));
return llvm::Error::success();
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -1012,6 +770,9 @@ llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
template <>
llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
switch (F) {
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
+ return llvm::Error::success();
case FieldId::F_parent:
I->Parent = std::move(R);
return llvm::Error::success();
@@ -1023,9 +784,17 @@ llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
switch (F) {
+ case FieldId::F_namespace:
+ I->Namespace.emplace_back(std::move(R));
+ return llvm::Error::success();
+ case FieldId::F_parent:
+ I->Parents.emplace_back(std::move(R));
+ return llvm::Error::success();
+ case FieldId::F_vparent:
+ I->VirtualParents.emplace_back(std::move(R));
+ return llvm::Error::success();
case FieldId::F_child_record:
- I->Children.Records.push_back(
- *allocatePtr<Reference>(TransientArena, std::move(R)));
+ I->Children.Records.emplace_back(std::move(R));
return llvm::Error::success();
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -1054,42 +823,54 @@ llvm::Error addReference(FriendInfo *Friend, Reference &&R, FieldId F) {
"Friend cannot contain this Reference");
}
-static auto &getList(ScopeChildren &C, FunctionInfo *) { return C.Functions; }
-static auto &getList(ScopeChildren &C, EnumInfo *) { return C.Enums; }
-static auto &getList(ScopeChildren &C, TypedefInfo *) { return C.Typedefs; }
-static auto &getList(ScopeChildren &C, ConceptInfo *) { return C.Concepts; }
-static auto &getList(ScopeChildren &C, VarInfo *) { return C.Variables; }
-
-template <typename T, typename = void> struct has_children : std::false_type {};
-template <typename T>
-struct has_children<T, std::void_t<decltype(std::declval<T>().Children)>>
- : std::is_same<decltype(std::declval<T>().Children), ScopeChildren> {};
-
-template <typename TargetChild, typename = void>
-struct is_valid_child : std::false_type {};
-template <typename TargetChild>
-struct is_valid_child<
- TargetChild, std::void_t<decltype(getList(std::declval<ScopeChildren &>(),
- std::declval<TargetChild *>()))>>
- : std::true_type {};
-
-template <typename Target, typename Child>
-static void addChild(Target I, Child &&R) {
- if constexpr (std::is_pointer_v<Target>) {
- using Pointee = std::remove_pointer_t<Target>;
- if constexpr (has_children<Pointee>::value) {
- using BareChild = std::remove_cv_t<std::remove_reference_t<Child>>;
- if constexpr (is_valid_child<BareChild>::value) {
- auto *Node = allocatePtr<BareChild>(std::move(R));
- getList(I->Children, Node).push_back(*Node);
- return;
- }
- }
- }
+template <typename T, typename ChildInfoType>
+static void addChild(T I, ChildInfoType &&R) {
ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid child type for info"));
}
+// Namespace children:
+template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
+ I->Children.Functions.emplace_back(std::move(R));
+}
+template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
+ I->Children.Enums.emplace_back(std::move(R));
+}
+template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
+ I->Children.Typedefs.emplace_back(std::move(R));
+}
+template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
+ I->Children.Concepts.emplace_back(std::move(R));
+}
+template <> void addChild(NamespaceInfo *I, VarInfo &&R) {
+ I->Children.Variables.emplace_back(std::move(R));
+}
+
+// Record children:
+template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
+ I->Children.Functions.emplace_back(std::move(R));
+}
+template <> void addChild(RecordInfo *I, EnumInfo &&R) {
+ I->Children.Enums.emplace_back(std::move(R));
+}
+template <> void addChild(RecordInfo *I, TypedefInfo &&R) {
+ I->Children.Typedefs.emplace_back(std::move(R));
+}
+template <> void addChild(RecordInfo *I, FriendInfo &&R) {
+ I->Friends.emplace_back(std::move(R));
+}
+
+// Other types of children:
+template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
+ I->Members.emplace_back(std::move(R));
+}
+template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
+ I->Bases.emplace_back(std::move(R));
+}
+template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
+ I->Children.Functions.emplace_back(std::move(R));
+}
+
// TemplateParam children. These go into either a TemplateInfo (for template
// parameters) or TemplateSpecializationInfo (for the specialization's
// parameters).
@@ -1098,6 +879,13 @@ template <typename T> static void addTemplateParam(T I, TemplateParamInfo &&P) {
llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid container for template parameter"));
}
+template <> void addTemplateParam(TemplateInfo *I, TemplateParamInfo &&P) {
+ I->Params.emplace_back(std::move(P));
+}
+template <>
+void addTemplateParam(TemplateSpecializationInfo *I, TemplateParamInfo &&P) {
+ I->Params.emplace_back(std::move(P));
+}
// Template info. These apply to either records or functions.
template <typename T> static void addTemplate(T I, TemplateInfo &&P) {
@@ -1137,6 +925,9 @@ template <typename T> static void addConstraint(T I, ConstraintInfo &&C) {
ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
"invalid container for constraint info"));
}
+template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) {
+ I->Constraints.emplace_back(std::move(C));
+}
// Read records from bitcode into a given info.
template <typename T>
@@ -1161,37 +952,6 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
}
// Read a block of records into a single info.
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, VarInfo *I) {
- return readBlockWithNamespace(ID, I);
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, TypedefInfo *I) {
- return readBlockWithNamespace(ID, I);
-}
-
-template <>
-llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, NamespaceInfo *I) {
- return readBlockWithNamespace(ID, I);
-}
-
-template <typename T>
-llvm::Error ClangDocBitcodeReader::readBlockWithNamespace(unsigned ID, T I) {
- llvm::SmallVector<Reference> LocalNamespaces;
- return parseBlock(
- ID, I,
- [&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
- },
- [&]() -> llvm::Error {
- if (!LocalNamespaces.empty())
- I->Namespace = allocateArray(LocalNamespaces, TransientArena);
- return llvm::Error::success();
- });
-}
-
template <typename T>
llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
return parseBlock(
@@ -1209,13 +969,13 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FriendInfo *I) {
return parseBlock(
ID, I,
[&](unsigned BlockOrCode) -> llvm::Expected<bool> {
- auto B = readSubBlockIfMatch(BlockOrCode, BI_FIELD_TYPE_BLOCK_ID,
- LocalParams);
- if (!B)
- return B.takeError();
- if (*B)
+ if (BlockOrCode == BI_FIELD_TYPE_BLOCK_ID) {
+ FieldTypeInfo FI;
+ if (auto Err = readBlock(BlockOrCode, &FI))
+ return std::move(Err);
+ LocalParams.push_back(std::move(FI));
return true;
-
+ }
return false;
},
[&]() -> llvm::Error {
@@ -1228,19 +988,27 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FriendInfo *I) {
});
}
+// TODO: fix inconsistentent returning of errors in add callbacks.
+// Once that's fixed, we only need one handleSubBlock.
template <typename InfoType, typename T, typename Callback>
llvm::Error ClangDocBitcodeReader::handleSubBlock(unsigned ID, T Parent,
Callback Function) {
InfoType Info;
if (auto Err = readBlock(ID, &Info))
return Err;
- if constexpr (std::is_void_v<
- std::invoke_result_t<Callback, T, InfoType &&>>) {
- Function(Parent, std::move(Info));
- return llvm::Error::success();
- } else {
- return Function(Parent, std::move(Info));
- }
+ Function(Parent, std::move(Info));
+ return llvm::Error::success();
+}
+
+template <typename InfoType, typename T, typename Callback>
+llvm::Error ClangDocBitcodeReader::handleTypeSubBlock(unsigned ID, T Parent,
+ Callback Function) {
+ InfoType Info;
+ if (auto Err = readBlock(ID, &Info))
+ return Err;
+ if (auto Err = Function(Parent, std::move(Info)))
+ return Err;
+ return llvm::Error::success();
}
template <typename T>
@@ -1264,15 +1032,15 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
return llvm::Error::success();
}
case BI_TYPE_BLOCK_ID: {
- return handleSubBlock<TypeInfo>(ID, I,
- CreateAddFunc(addTypeInfo<T, TypeInfo>));
+ return handleTypeSubBlock<TypeInfo>(
+ ID, I, CreateAddFunc(addTypeInfo<T, TypeInfo>));
}
case BI_FIELD_TYPE_BLOCK_ID: {
- return handleSubBlock<FieldTypeInfo>(
+ return handleTypeSubBlock<FieldTypeInfo>(
ID, I, CreateAddFunc(addTypeInfo<T, FieldTypeInfo>));
}
case BI_MEMBER_TYPE_BLOCK_ID: {
- return handleSubBlock<MemberTypeInfo>(
+ return handleTypeSubBlock<MemberTypeInfo>(
ID, I, CreateAddFunc(addTypeInfo<T, MemberTypeInfo>));
}
case BI_REFERENCE_BLOCK_ID: {
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.h b/clang-tools-extra/clang-doc/BitcodeReader.h
index 4585cb454f408..d3499fdee0f5d 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.h
+++ b/clang-tools-extra/clang-doc/BitcodeReader.h
@@ -44,32 +44,12 @@ class ClangDocBitcodeReader {
// Read a block of records into a single Info struct, calls readRecord on each
// record found.
template <typename T> llvm::Error readBlock(unsigned ID, T I);
- template <typename T> llvm::Error readBlockWithNamespace(unsigned ID, T I);
template <typename T, typename BlockBeginHandler, typename BlockEndHandler,
typename RecordHandler>
llvm::Error parseBlock(unsigned ID, T I, BlockBeginHandler &&BBH,
BlockEndHandler &&BEH, RecordHandler &&RH);
- template <typename T, typename BlockBeginHandler, typename BlockEndHandler>
- llvm::Error parseBlock(unsigned ID, T I, BlockBeginHandler &&BBH,
- BlockEndHandler &&BEH);
-
- template <typename ChildType>
- llvm::Expected<bool> readSubBlockIfMatch(unsigned ID, unsigned TargetID,
- llvm::SmallVectorImpl<ChildType> &V);
-
- struct ReferenceMap {
- FieldId Field;
- llvm::SmallVectorImpl<Reference> *Vec;
- };
-
- template <typename InfoT>
- llvm::Expected<bool>
- routeReferenceBlock(unsigned ID, llvm::SmallVectorImpl<Reference> &Namespaces,
- InfoT *I,
- std::initializer_list<ReferenceMap> Mappings = {});
-
// Step through a block of records to find the next data field.
template <typename T> llvm::Error readSubBlock(unsigned ID, T I);
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 4854c6114b760..e895d641a6000 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -27,7 +27,6 @@ class JSONGenerator : public Generator {
void serializeCommonChildren(
const ScopeChildren &Children, json::Object &Obj,
std::optional<ReferenceFunc> MDReferenceLambda = std::nullopt);
- void serializeContexts(Info *I, llvm::StringMap<OwnedPtr<Info>> &Infos);
void serializeInfo(const ConstraintInfo &I, Object &Obj);
void serializeInfo(const TemplateInfo &Template, Object &Obj);
void serializeInfo(const ConceptInfo &I, Object &Obj);
@@ -62,12 +61,10 @@ class JSONGenerator : public Generator {
};
}
- llvm::DenseMap<const Info *, SmallVector<Context, 4>> ContextsMap;
- const ClangDocContext *CDCtx;
- bool Markdown;
-
public:
static const char *Format;
+ const ClangDocContext *CDCtx;
+ bool Markdown;
Error generateDocumentation(StringRef RootDir,
llvm::StringMap<OwnedPtr<doc::Info>> Infos,
@@ -323,20 +320,13 @@ static Object serializeComment(const CommentInfo &I, Object &Description) {
/// Creates Contexts for namespaces and records to allow for navigation.
void JSONGenerator::generateContext(const Info &I, Object &Obj) {
- Obj["Contexts"] = json::Array();
- Obj["HasContexts"] = true;
-
- auto It = ContextsMap.find(&I);
- if (It == ContextsMap.end() || It->second.empty())
- return;
-
- auto &ContextArrayRef = *Obj["Contexts"].getAsArray();
- const auto &Contexts = It->second;
- ContextArrayRef.reserve(Contexts.size());
+ json::Value ContextArray = json::Array();
+ auto &ContextArrayRef = *ContextArray.getAsArray();
+ ContextArrayRef.reserve(I.Contexts.size());
std::string CurrentRelativePath;
bool PreviousRecord = false;
- for (const auto &Current : Contexts) {
+ for (const auto &Current : I.Contexts) {
json::Value ContextVal = Object();
Object &Context = *ContextVal.getAsObject();
serializeReference(Current, Context);
@@ -382,9 +372,11 @@ void JSONGenerator::generateContext(const Info &I, Object &Obj) {
}
ContextArrayRef.back().getAsObject()->insert({"End", true});
+ Obj["Contexts"] = ContextArray;
+ Obj["HasContexts"] = true;
}
-static void serializeDescription(const OwningVec<CommentInfo> &Description,
+static void serializeDescription(llvm::ArrayRef<CommentInfo> Description,
json::Object &Obj, StringRef Key = "") {
if (Description.empty())
return;
@@ -437,8 +429,7 @@ void JSONGenerator::serializeCommonAttributes(const Info &I,
Obj["Location"] = serializeLocation(Symbol->DefLoc.value());
}
- auto It = ContextsMap.find(&I);
- if (It != ContextsMap.end() && !It->second.empty())
+ if (!I.Contexts.empty())
generateContext(I, Obj);
}
@@ -835,9 +826,9 @@ SmallString<16> JSONGenerator::determineFileName(Info *I,
/// \param CDCtxIndex Passed by copy since clang-doc's context is passed to the
/// generator as `const`
-static std::vector<Index> preprocessCDCtxIndex(Index CDCtxIndex) {
+static OwningVec<Index> preprocessCDCtxIndex(Index CDCtxIndex) {
CDCtxIndex.sort();
- std::vector<Index> Processed;
+ OwningVec<Index> Processed;
Processed.reserve(CDCtxIndex.Children.size());
for (const auto *Idx : CDCtxIndex.getSortedChildren()) {
Index NewIdx = *Idx;
@@ -857,7 +848,7 @@ Error JSONGenerator::serializeAllFiles(const ClangDocContext &CDCtx,
StringRef RootDir) {
json::Value ObjVal = Object();
Object &Obj = *ObjVal.getAsObject();
- std::vector<Index> IndexCopy = preprocessCDCtxIndex(CDCtx.Idx);
+ OwningVec<Index> IndexCopy = preprocessCDCtxIndex(CDCtx.Idx);
serializeArray(IndexCopy, Obj, "Index", serializeReferenceLambda());
SmallString<128> Path;
sys::path::append(Path, RootDir, "json", "all_files.json");
@@ -920,12 +911,10 @@ Error JSONGenerator::serializeIndex(StringRef RootDir) {
return Error::success();
}
-void JSONGenerator::serializeContexts(Info *I,
- StringMap<OwnedPtr<Info>> &Infos) {
+static void serializeContexts(Info *I, StringMap<OwnedPtr<Info>> &Infos) {
if (I->USR == GlobalNamespaceID)
return;
auto ParentUSR = I->ParentUSR;
- auto &LocalContexts = ContextsMap[I];
while (true) {
// Infos may not have the ParentUSR, if its been filtered (public or path),
@@ -939,12 +928,12 @@ void JSONGenerator::serializeContexts(Info *I,
Context GlobalRef(ParentInfo->USR, "Global Namespace",
InfoType::IT_namespace, "GlobalNamespace", "",
SmallString<16>("index"));
- LocalContexts.push_back(GlobalRef);
- break;
+ I->Contexts.push_back(GlobalRef);
+ return;
}
Context ParentRef(*ParentInfo);
- LocalContexts.push_back(ParentRef);
+ I->Contexts.push_back(ParentRef);
ParentUSR = ParentInfo->ParentUSR;
}
}
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index 9ccb7a8ccd633..b0253c5d71bfc 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -31,7 +31,8 @@ static std::string genEmphasis(const Twine &Text) {
return "**" + Text.str() + "**";
}
-static std::string genReferenceList(llvm::ArrayRef<Reference> Refs) {
+static std::string
+genReferenceList(const llvm::SmallVectorImpl<Reference> &Refs) {
std::string Buffer;
llvm::raw_string_ostream Stream(Buffer);
for (const auto &R : Refs) {
@@ -81,7 +82,7 @@ class TableCommentWriter {
public:
explicit TableCommentWriter(llvm::raw_ostream &OS) : OS(OS) {}
- void write(const OwningVec<CommentInfo> &Comments) {
+ void write(llvm::ArrayRef<CommentInfo> Comments) {
for (const auto &C : Comments)
writeTableSafeComment(C);
@@ -435,7 +436,7 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) {
OS << " for " << CDCtx.ProjectName;
OS << "\n\n";
- std::vector<const Index *> Children = CDCtx.Idx.getSortedChildren();
+ OwningVec<const Index *> Children = CDCtx.Idx.getSortedChildren();
for (const auto *C : Children)
serializeReference(OS, *C, 0);
@@ -454,7 +455,7 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) {
FileErr.message());
CDCtx.Idx.sort();
OS << "# " << CDCtx.ProjectName << " C/C++ Reference\n\n";
- std::vector<const Index *> Children = CDCtx.Idx.getSortedChildren();
+ OwningVec<const Index *> Children = CDCtx.Idx.getSortedChildren();
for (const auto *C : Children) {
if (!C->Children.empty()) {
const char *Type;
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 499ab5638b34e..583a0fe43b40c 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -43,9 +43,6 @@ void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
if (CDCtx.FTimeTrace)
llvm::timeTraceProfilerInitialize(200, "clang-doc");
TraverseDecl(Context.getTranslationUnitDecl());
-
- TransientArena.Reset();
-
if (CDCtx.FTimeTrace)
llvm::timeTraceProfilerFinishThread();
}
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index 50c5f9bb1d071..42f85c39655dd 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -105,6 +105,17 @@ static llvm::Expected<OwnedPtr<Info>> reduce(OwningPtrArray<Info> &Values) {
return std::move(Merged);
}
+// Return the index of the matching child in the vector, or -1 if merge is not
+// necessary.
+template <typename T>
+static int getChildIndexIfExists(OwningVec<T> &Children, T &ChildToMerge) {
+ for (unsigned long I = 0; I < Children.size(); I++) {
+ if (ChildToMerge.USR == Children[I].USR)
+ return I;
+ }
+ return -1;
+}
+
template <typename T>
static void reduceChildren(llvm::simple_ilist<T> &Children,
llvm::simple_ilist<T> &&ChildrenToMerge) {
@@ -115,145 +126,34 @@ static void reduceChildren(llvm::simple_ilist<T> &Children,
auto It = llvm::find_if(
Children, [&](const T &C) { return C.USR == ChildToMerge->USR; });
if (It == Children.end()) {
- T *NewChild = allocatePtr<T>(PersistentArena, ChildToMerge->USR);
- NewChild->merge(std::move(*ChildToMerge));
- Children.push_back(*NewChild);
+ Children.push_back(*ChildToMerge);
} else {
It->merge(std::move(*ChildToMerge));
}
}
}
-template <>
-void reduceChildren<Reference>(
- llvm::simple_ilist<Reference> &Children,
- llvm::simple_ilist<Reference> &&ChildrenToMerge) {
- while (!ChildrenToMerge.empty()) {
- Reference *ChildToMerge = &ChildrenToMerge.front();
- ChildrenToMerge.pop_front();
-
- auto It = llvm::find_if(Children, [&](const Reference &C) {
- return C.USR == ChildToMerge->USR;
- });
- if (It == Children.end()) {
- Reference *NewChild = allocatePtr<Reference>(PersistentArena);
- NewChild->USR = ChildToMerge->USR;
- NewChild->RefType = ChildToMerge->RefType;
- NewChild->merge(std::move(*ChildToMerge));
- Children.push_back(*NewChild);
- } else {
- It->merge(std::move(*ChildToMerge));
+template <typename T>
+static void reduceChildren(OwningVec<T> &Children,
+ OwningVec<T> &&ChildrenToMerge) {
+ for (auto &ChildToMerge : ChildrenToMerge) {
+ int MergeIdx = getChildIndexIfExists(Children, ChildToMerge);
+ if (MergeIdx == -1) {
+ Children.push_back(std::move(ChildToMerge));
+ continue;
}
+ Children[MergeIdx].merge(std::move(ChildToMerge));
}
}
template <typename Container>
static void mergeUnkeyed(Container &Target, Container &&Source) {
- using T = typename Container::value_type;
- while (!Source.empty()) {
- auto &Item = Source.front();
- Source.pop_front();
- if (llvm::none_of(Target, [&](const auto &E) { return E == Item; })) {
- T *NewItem = allocatePtr<T>(PersistentArena, Item);
- Target.push_back(*NewItem);
- }
- }
-}
-
-template <>
-void mergeUnkeyed<OwningVec<CommentInfo>>(OwningVec<CommentInfo> &Target,
- OwningVec<CommentInfo> &&Source) {
- while (!Source.empty()) {
- auto &Item = Source.front();
- Source.pop_front();
- if (llvm::none_of(Target, [&](const auto &E) { return E == Item; })) {
- CommentInfo *NewItem =
- allocatePtr<CommentInfo>(PersistentArena, Item, PersistentArena);
- Target.push_back(*NewItem);
- }
+ for (auto &Item : Source) {
+ if (llvm::none_of(Target, [&](const auto &E) { return E == Item; }))
+ Target.push_back(std::move(Item));
}
}
-llvm::Error mergeSingleInfo(doc::OwnedPtr<doc::Info> &Reduced,
- doc::OwnedPtr<doc::Info> &&NewInfo,
- llvm::BumpPtrAllocator &Arena) {
- if (!Reduced) {
- switch (NewInfo->IT) {
- case InfoType::IT_namespace:
- Reduced = allocatePtr<NamespaceInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_record:
- Reduced = allocatePtr<RecordInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_enum:
- Reduced = allocatePtr<EnumInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_function:
- Reduced = allocatePtr<FunctionInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_typedef:
- Reduced = allocatePtr<TypedefInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_concept:
- Reduced = allocatePtr<ConceptInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_variable:
- Reduced = allocatePtr<VarInfo>(Arena, NewInfo->USR);
- break;
- case InfoType::IT_friend:
- Reduced = allocatePtr<FriendInfo>(Arena, NewInfo->USR);
- break;
- default:
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "unknown info type");
- }
- }
-
- if (Reduced->IT != NewInfo->IT)
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "info types mismatch");
-
- switch (Reduced->IT) {
- case InfoType::IT_namespace:
- static_cast<NamespaceInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<NamespaceInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_record:
- static_cast<RecordInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<RecordInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_enum:
- static_cast<EnumInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<EnumInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_function:
- static_cast<FunctionInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<FunctionInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_typedef:
- static_cast<TypedefInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<TypedefInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_concept:
- static_cast<ConceptInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<ConceptInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_variable:
- static_cast<VarInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<VarInfo *>(getPtr(NewInfo))));
- break;
- case InfoType::IT_friend:
- static_cast<FriendInfo *>(getPtr(Reduced))
- ->merge(std::move(*static_cast<FriendInfo *>(getPtr(NewInfo))));
- break;
- default:
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "unknown info type");
- }
-
- return llvm::Error::success();
-}
-
// Dispatch function.
llvm::Expected<OwnedPtr<Info>> mergeInfos(OwningPtrArray<Info> &Values) {
if (Values.empty() || !Values[0])
@@ -284,20 +184,6 @@ llvm::Expected<OwnedPtr<Info>> mergeInfos(OwningPtrArray<Info> &Values) {
llvm_unreachable("unhandled enumerator");
}
-TemplateSpecializationInfo::TemplateSpecializationInfo(
- const TemplateSpecializationInfo &Other, llvm::BumpPtrAllocator &Arena)
- : SpecializationOf(Other.SpecializationOf) {
- Params = allocateArray(Other.Params, Arena);
-}
-
-TemplateInfo::TemplateInfo(const TemplateInfo &Other,
- llvm::BumpPtrAllocator &Arena) {
- Params = allocateArray(Other.Params, Arena);
- if (Other.Specialization)
- Specialization = TemplateSpecializationInfo(*Other.Specialization, Arena);
- Constraints = allocateArray(Other.Constraints, Arena);
-}
-
bool CommentInfo::operator==(const CommentInfo &Other) const {
auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName,
SelfClosing, Explicit, AttrKeys, AttrValues, Args);
@@ -333,28 +219,6 @@ bool CommentInfo::operator<(const CommentInfo &Other) const {
return false;
}
-CommentInfo::CommentInfo(const CommentInfo &Other,
- llvm::BumpPtrAllocator &Arena) {
- Kind = Other.Kind;
- Direction = Other.Direction;
- Name = Other.Name;
- ParamName = Other.ParamName;
- CloseName = Other.CloseName;
- SelfClosing = Other.SelfClosing;
- Explicit = Other.Explicit;
- Text = Other.Text;
- AttrKeys = allocateArray(Other.AttrKeys, Arena);
- AttrValues = allocateArray(Other.AttrValues, Arena);
- Args = allocateArray(Other.Args, Arena);
- if (!Other.Children.empty()) {
- CommentInfo *NewArray = Arena.Allocate<CommentInfo>(Other.Children.size());
- for (size_t Idx = 0; Idx < Other.Children.size(); ++Idx) {
- new (NewArray + Idx) CommentInfo(Other.Children[Idx], Arena);
- }
- Children = llvm::ArrayRef<CommentInfo>(NewArray, Other.Children.size());
- }
-}
-
static llvm::SmallString<64>
calculateRelativeFilePath(const InfoType &Type, const StringRef &Path,
const StringRef &Name, const StringRef &CurrentPath) {
@@ -411,8 +275,6 @@ void Reference::merge(Reference &&Other) {
Name = Other.Name;
if (Path.empty())
Path = Other.Path;
- if (QualName.empty())
- QualName = Other.QualName;
if (DocumentationFileName.empty())
DocumentationFileName = Other.DocumentationFileName;
}
@@ -427,31 +289,6 @@ void FriendInfo::merge(FriendInfo &&Other) {
SymbolInfo::merge(std::move(Other));
}
-FriendInfo::FriendInfo(const FriendInfo &Other, llvm::BumpPtrAllocator &Arena)
- : SymbolInfo(Other, Arena) {
- Ref = Other.Ref;
- if (Other.Template)
- Template.emplace(*Other.Template, Arena);
- if (Other.ReturnType)
- ReturnType = Other.ReturnType;
- if (!Other.Params.empty())
- Params = allocateArray(Other.Params, Arena);
- IsClass = Other.IsClass;
-}
-
-Info::Info(const Info &Other, llvm::BumpPtrAllocator &Arena)
- : Path(Other.Path), Name(Other.Name),
- DocumentationFileName(Other.DocumentationFileName), USR(Other.USR),
- ParentUSR(Other.ParentUSR), IT(Other.IT) {
- Namespace = allocateArray(Other.Namespace, Arena);
- if (!Other.Description.empty()) {
- for (const auto &Desc : Other.Description) {
- CommentInfo *NewDesc = allocatePtr<CommentInfo>(Arena, Desc, Arena);
- Description.push_back(*NewDesc);
- }
- }
-}
-
void Info::mergeBase(Info &&Other) {
assert(mergeable(Other));
if (USR == EmptySID)
@@ -460,8 +297,8 @@ void Info::mergeBase(Info &&Other) {
Name = Other.Name;
if (Path == "")
Path = Other.Path;
- if (Namespace.empty() && !Other.Namespace.empty())
- Namespace = allocateArray(Other.Namespace, PersistentArena);
+ if (Namespace.empty())
+ Namespace = std::move(Other.Namespace);
// Unconditionally extend the description, since each decl may have a comment.
mergeUnkeyed(Description, std::move(Other.Description));
if (ParentUSR == EmptySID)
@@ -474,17 +311,6 @@ bool Info::mergeable(const Info &Other) {
return IT == Other.IT && USR == Other.USR;
}
-SymbolInfo::SymbolInfo(const SymbolInfo &Other, llvm::BumpPtrAllocator &Arena)
- : Info(Other, Arena), DefLoc(Other.DefLoc), MangledName(Other.MangledName),
- IsStatic(Other.IsStatic) {
- if (!Other.Loc.empty()) {
- for (const auto &L : Other.Loc) {
- Location *NewL = allocatePtr<Location>(Arena, L);
- Loc.push_back(*NewL);
- }
- }
-}
-
void SymbolInfo::merge(SymbolInfo &&Other) {
assert(mergeable(Other));
if (!DefLoc)
@@ -494,8 +320,6 @@ void SymbolInfo::merge(SymbolInfo &&Other) {
mergeBase(std::move(Other));
if (MangledName.empty())
MangledName = std::move(Other.MangledName);
- if (!IsStatic)
- IsStatic = Other.IsStatic;
}
NamespaceInfo::NamespaceInfo(SymbolID USR, StringRef Name, StringRef Path)
@@ -517,76 +341,37 @@ void NamespaceInfo::merge(NamespaceInfo &&Other) {
RecordInfo::RecordInfo(SymbolID USR, StringRef Name, StringRef Path)
: SymbolInfo(InfoType::IT_record, USR, Name, Path) {}
-// FIXME: This constructor is currently unsafe for cross-arena copies of
-// populated records. Because a default copy of ScopeChildren will shallow-copy
-// the intrusive pointers, leading to a use-after-free when the TransientArena
-// is reset. Subsequent patches will address this by deep-copying children
-// individually via reduceChildren.
-RecordInfo::RecordInfo(const RecordInfo &Other, llvm::BumpPtrAllocator &Arena)
- : SymbolInfo(Other, Arena), TagType(Other.TagType),
- IsTypeDef(Other.IsTypeDef) {
- Members = deepCopyArray(Other.Members, Arena);
- Parents = allocateArray(Other.Parents, Arena);
- VirtualParents = allocateArray(Other.VirtualParents, Arena);
- Bases = deepCopyArray(Other.Bases, Arena);
- Friends = deepCopyArray(Other.Friends, Arena);
-}
-
-MemberTypeInfo::MemberTypeInfo(const MemberTypeInfo &Other,
- llvm::BumpPtrAllocator &Arena)
- : FieldTypeInfo(Other), Access(Other.Access), IsStatic(Other.IsStatic) {
- if (!Other.Description.empty()) {
- for (const auto &Desc : Other.Description) {
- CommentInfo *NewDesc = allocatePtr<CommentInfo>(Arena, Desc, Arena);
- Description.push_back(*NewDesc);
- }
- }
-}
-
void RecordInfo::merge(RecordInfo &&Other) {
assert(mergeable(Other));
if (!llvm::to_underlying(TagType))
TagType = Other.TagType;
IsTypeDef = IsTypeDef || Other.IsTypeDef;
- if (Members.empty() && !Other.Members.empty())
- Members = deepCopyArray(Other.Members, PersistentArena);
- if (Bases.empty() && !Other.Bases.empty())
- Bases = deepCopyArray(Other.Bases, PersistentArena);
- if (Parents.empty() && !Other.Parents.empty())
- Parents = allocateArray(Other.Parents, PersistentArena);
- if (VirtualParents.empty() && !Other.VirtualParents.empty())
- VirtualParents = allocateArray(Other.VirtualParents, PersistentArena);
- if (Friends.empty() && !Other.Friends.empty())
- Friends = deepCopyArray(Other.Friends, PersistentArena);
+ if (Members.empty())
+ Members = std::move(Other.Members);
+ if (Bases.empty())
+ Bases = std::move(Other.Bases);
+ if (Parents.empty())
+ Parents = std::move(Other.Parents);
+ if (VirtualParents.empty())
+ VirtualParents = std::move(Other.VirtualParents);
+ if (Friends.empty())
+ Friends = std::move(Other.Friends);
// Reduce children if necessary.
reduceChildren(Children.Records, std::move(Other.Children.Records));
reduceChildren(Children.Functions, std::move(Other.Children.Functions));
reduceChildren(Children.Enums, std::move(Other.Children.Enums));
reduceChildren(Children.Typedefs, std::move(Other.Children.Typedefs));
SymbolInfo::merge(std::move(Other));
- if (!Template && Other.Template)
- Template = TemplateInfo(*Other.Template, PersistentArena);
-}
-
-EnumValueInfo::EnumValueInfo(const EnumValueInfo &Other,
- llvm::BumpPtrAllocator &Arena)
- : Name(Other.Name), Value(Other.Value), ValueExpr(Other.ValueExpr) {
- if (!Other.Description.empty()) {
- for (const auto &Desc : Other.Description) {
- CommentInfo *NewDesc = allocatePtr<CommentInfo>(Arena, Desc, Arena);
- Description.push_back(*NewDesc);
- }
- }
+ if (!Template)
+ Template = Other.Template;
}
void EnumInfo::merge(EnumInfo &&Other) {
assert(mergeable(Other));
if (!Scoped)
Scoped = Other.Scoped;
- if (!BaseType && Other.BaseType)
- BaseType = std::move(Other.BaseType);
- if (Members.empty() && !Other.Members.empty())
- Members = deepCopyArray(Other.Members, PersistentArena);
+ if (Members.empty())
+ Members = std::move(Other.Members);
SymbolInfo::merge(std::move(Other));
}
@@ -600,11 +385,11 @@ void FunctionInfo::merge(FunctionInfo &&Other) {
ReturnType = std::move(Other.ReturnType);
if (Parent.USR == EmptySID && Parent.Name == "")
Parent = std::move(Other.Parent);
- if (Params.empty() && !Other.Params.empty())
- Params = allocateArray(Other.Params, PersistentArena);
+ if (Params.empty())
+ Params = std::move(Other.Params);
SymbolInfo::merge(std::move(Other));
- if (!Template && Other.Template)
- Template = TemplateInfo(*Other.Template, PersistentArena);
+ if (!Template)
+ Template = Other.Template;
}
void TypedefInfo::merge(TypedefInfo &&Other) {
@@ -613,8 +398,8 @@ void TypedefInfo::merge(TypedefInfo &&Other) {
IsUsing = Other.IsUsing;
if (Underlying.Type.Name == "")
Underlying = Other.Underlying;
- if (!Template && Other.Template)
- Template = TemplateInfo(*Other.Template, PersistentArena);
+ if (!Template)
+ Template = Other.Template;
SymbolInfo::merge(std::move(Other));
}
@@ -624,11 +409,10 @@ void ConceptInfo::merge(ConceptInfo &&Other) {
IsType = Other.IsType;
if (ConstraintExpression.empty())
ConstraintExpression = std::move(Other.ConstraintExpression);
- if (Template.Constraints.empty() && !Other.Template.Constraints.empty())
- Template.Constraints =
- allocateArray(Other.Template.Constraints, PersistentArena);
- if (Template.Params.empty() && !Other.Template.Params.empty())
- Template.Params = allocateArray(Other.Template.Params, PersistentArena);
+ if (Template.Constraints.empty())
+ Template.Constraints = std::move(Other.Template.Constraints);
+ if (Template.Params.empty())
+ Template.Params = std::move(Other.Template.Params);
SymbolInfo::merge(std::move(Other));
}
@@ -643,11 +427,6 @@ void VarInfo::merge(VarInfo &&Other) {
BaseRecordInfo::BaseRecordInfo() : RecordInfo() {}
-BaseRecordInfo::BaseRecordInfo(const BaseRecordInfo &Other,
- llvm::BumpPtrAllocator &Arena)
- : RecordInfo(Other, Arena), Access(Other.Access),
- IsVirtual(Other.IsVirtual), IsParent(Other.IsParent) {}
-
BaseRecordInfo::BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path,
bool IsVirtual, AccessSpecifier Access,
bool IsParent)
@@ -705,8 +484,8 @@ bool Index::operator<(const Index &Other) const {
return Name < Other.Name;
}
-std::vector<const Index *> Index::getSortedChildren() const {
- std::vector<const Index *> SortedChildren;
+OwningVec<const Index *> Index::getSortedChildren() const {
+ OwningVec<const Index *> SortedChildren;
SortedChildren.reserve(Children.size());
for (const auto &[_, C] : Children)
SortedChildren.push_back(&C);
@@ -750,12 +529,12 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
void ScopeChildren::sort() {
Namespaces.sort();
- Records.sort();
- Functions.sort();
- Enums.sort();
- Typedefs.sort();
- Concepts.sort();
- Variables.sort();
+ llvm::sort(Records);
+ llvm::sort(Functions);
+ llvm::sort(Enums);
+ llvm::sort(Typedefs);
+ llvm::sort(Concepts);
+ llvm::sort(Variables);
}
} // namespace doc
} // namespace clang
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 5f404463b012e..9208b77fc8606 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -52,7 +52,6 @@ class ConcurrentStringPool {
ConcurrentStringPool &getGlobalStringPool();
extern thread_local llvm::BumpPtrAllocator TransientArena;
-extern thread_local llvm::BumpPtrAllocator PersistentArena;
inline StringRef internString(const Twine &T) {
if (T.isTriviallyEmpty())
@@ -73,8 +72,8 @@ inline StringRef internString(const Twine &T) {
}
template <typename T>
-llvm::ArrayRef<T> allocateArray(llvm::SmallVectorImpl<T> &V,
- llvm::BumpPtrAllocator &Alloc) {
+inline llvm::ArrayRef<T> allocateArray(llvm::ArrayRef<T> V,
+ llvm::BumpPtrAllocator &Alloc) {
if (V.empty())
return llvm::ArrayRef<T>();
T *Allocated = (T *)Alloc.Allocate<T>(V.size());
@@ -82,31 +81,9 @@ llvm::ArrayRef<T> allocateArray(llvm::SmallVectorImpl<T> &V,
return llvm::ArrayRef<T>(Allocated, V.size());
}
-template <typename T>
-llvm::ArrayRef<T> allocateArray(llvm::ArrayRef<T> V,
- llvm::BumpPtrAllocator &Alloc) {
- if (V.empty())
- return llvm::ArrayRef<T>();
- T *Allocated = (T *)Alloc.Allocate<T>(V.size());
- std::uninitialized_copy(V.begin(), V.end(), Allocated);
- return llvm::ArrayRef<T>(Allocated, V.size());
-}
-
-template <typename T>
-llvm::ArrayRef<T> deepCopyArray(llvm::ArrayRef<T> V,
- llvm::BumpPtrAllocator &Alloc) {
- if (V.empty())
- return llvm::ArrayRef<T>();
- T *Allocated = (T *)Alloc.Allocate<T>(V.size());
- for (size_t Idx = 0; Idx < V.size(); ++Idx) {
- new (Allocated + Idx) T(V[Idx], Alloc);
- }
- return llvm::ArrayRef<T>(Allocated, V.size());
-}
-
// An abstraction for owned pointers. Initially mapped to OwnedPtr,
// to be eventually transitioned to bare pointers in an arena.
-template <typename T> using OwnedPtr = T *;
+template <typename T> using OwnedPtr = std::unique_ptr<T>;
// An abstraction for vectors that are populated and read sequentially.
// To be eventually transitioned to llvm::ArrayRef for arena storage.
@@ -114,7 +91,7 @@ template <typename T> using OwningArray = std::vector<T>;
// An abstraction for lists that are dynamically managed (inserted/removed).
// To be eventually transitioned to llvm::simple_ilist.
-template <typename T> using OwningVec = llvm::simple_ilist<T>;
+template <typename T> using OwningVec = std::vector<T>;
// An abstraction for dynamic lists of owned pointers.
// To be eventually transitioned to llvm::simple_ilist<T*> or similar.
@@ -128,10 +105,9 @@ template <typename T> using OwningPtrArray = std::vector<OwnedPtr<T>>;
// allocation mechanism.
template <typename T, typename... Args>
OwnedPtr<T> allocatePtr(Args &&...args) {
- return new (TransientArena.Allocate<T>()) T(std::forward<Args>(args)...);
+ return std::make_unique<T>(std::forward<Args>(args)...);
}
-// An overload to explicitly allocate on an arena, returning a bare pointer.
template <typename T, typename... Args>
T *allocatePtr(llvm::BumpPtrAllocator &Alloc, Args &&...args) {
return new (Alloc.Allocate<T>()) T(std::forward<Args>(args)...);
@@ -139,7 +115,7 @@ T *allocatePtr(llvm::BumpPtrAllocator &Alloc, Args &&...args) {
// A helper function to access the underlying pointer from an owned pointer,
// abstracting away the pointer dereferencing mechanism.
-template <typename T> T *getPtr(const OwnedPtr<T> &O) { return O; }
+template <typename T> T *getPtr(const OwnedPtr<T> &O) { return O.get(); }
// SHA1'd hash of a USR.
using SymbolID = std::array<uint8_t, 20>;
@@ -193,7 +169,6 @@ struct CommentInfo : public llvm::ilist_node<CommentInfo> {
CommentInfo() = default;
CommentInfo(const CommentInfo &Other) = default;
CommentInfo &operator=(const CommentInfo &Other) = default;
- CommentInfo(const CommentInfo &Other, llvm::BumpPtrAllocator &Arena);
CommentInfo(CommentInfo &&Other) = default;
CommentInfo &operator=(CommentInfo &&Other) = default;
@@ -219,11 +194,11 @@ struct CommentInfo : public llvm::ilist_node<CommentInfo> {
llvm::ArrayRef<CommentInfo>
Children; // List of child comments for this CommentInfo.
- StringRef Direction = {}; // Parameter direction (for (T)ParamCommand).
- StringRef Name = {}; // Name of the comment (for Verbatim and HTML).
- StringRef ParamName = {}; // Parameter name (for (T)ParamCommand).
- StringRef CloseName = {}; // Closing tag name (for VerbatimBlock).
- StringRef Text = {}; // Text of the comment.
+ StringRef Direction; // Parameter direction (for (T)ParamCommand).
+ StringRef Name; // Name of the comment (for Verbatim and HTML).
+ StringRef ParamName; // Parameter name (for (T)ParamCommand).
+ StringRef CloseName; // Closing tag name (for VerbatimBlock).
+ StringRef Text; // Text of the comment.
llvm::ArrayRef<StringRef> AttrKeys; // List of attribute keys (for HTML).
llvm::ArrayRef<StringRef>
AttrValues; // List of attribute values for each key (for HTML).
@@ -285,17 +260,17 @@ struct Reference : public llvm::ilist_node<Reference> {
// Name of type (possibly unresolved). Not including namespaces or template
// parameters (so for a std::vector<int> this would be "vector"). See also
// QualName.
- StringRef Name = {};
+ StringRef Name;
// Full qualified name of this type, including namespaces and template
// parameter (for example this could be "std::vector<int>"). Contrast to
// Name.
- StringRef QualName = {};
+ StringRef QualName;
// Path of directory where the clang-doc generated file will be saved
// (possibly unresolved)
- StringRef Path = {};
- StringRef DocumentationFileName = {};
+ StringRef Path;
+ StringRef DocumentationFileName;
};
// A Context is a reference that holds a relative path from a certain Info's
@@ -305,7 +280,7 @@ struct Context : public Reference {
StringRef Path, StringRef DocumentationFileName)
: Reference(USR, Name, IT, QualName, Path, DocumentationFileName) {}
explicit Context(const Info &I);
- StringRef RelativePath = {};
+ StringRef RelativePath;
};
// Holds the children of a record or namespace.
@@ -317,7 +292,7 @@ struct ScopeChildren {
//
// Namespaces are not syntactically valid as children of records, but making
// this general for all possible container types reduces code complexity.
- OwningVec<Reference> Namespaces;
+ llvm::simple_ilist<Reference> Namespaces;
OwningVec<Reference> Records;
OwningVec<FunctionInfo> Functions;
OwningVec<EnumInfo> Enums;
@@ -359,19 +334,15 @@ struct TemplateParamInfo {
// The literal contents of the code for that specifies this template parameter
// for this declaration. Typical values will be "class T" and
// "typename T = int".
- StringRef Contents = {};
+ StringRef Contents;
};
struct TemplateSpecializationInfo {
- TemplateSpecializationInfo() = default;
- TemplateSpecializationInfo(const TemplateSpecializationInfo &Other,
- llvm::BumpPtrAllocator &Arena);
-
// Indicates the declaration that this specializes.
SymbolID SpecializationOf;
// Template parameters applying to the specialized record/function.
- llvm::ArrayRef<TemplateParamInfo> Params;
+ OwningVec<TemplateParamInfo> Params;
};
struct ConstraintInfo {
@@ -380,21 +351,18 @@ struct ConstraintInfo {
: ConceptRef(USR, Name, InfoType::IT_concept) {}
Reference ConceptRef;
- StringRef ConstraintExpr = {};
+ StringRef ConstraintExpr;
};
// Records the template information for a struct or function that is a template
// or an explicit template specialization.
struct TemplateInfo {
- TemplateInfo() = default;
- TemplateInfo(const TemplateInfo &Other, llvm::BumpPtrAllocator &Arena);
-
// May be empty for non-partial specializations.
- llvm::ArrayRef<TemplateParamInfo> Params;
+ OwningVec<TemplateParamInfo> Params;
// Set when this is a specialization of another record/function.
std::optional<TemplateSpecializationInfo> Specialization;
- llvm::ArrayRef<ConstraintInfo> Constraints;
+ OwningVec<ConstraintInfo> Constraints;
};
// Info for field types.
@@ -410,27 +378,24 @@ struct FieldTypeInfo : public TypeInfo {
std::tie(Other.Type, Other.Name, Other.DefaultValue);
}
- StringRef Name = {}; // Name associated with this info.
+ StringRef Name; // Name associated with this info.
// When used for function parameters, contains the string representing the
// expression of the default value, if any.
- StringRef DefaultValue = {};
+ StringRef DefaultValue;
};
// Info for member types.
struct MemberTypeInfo : public FieldTypeInfo {
MemberTypeInfo() = default;
- MemberTypeInfo(const MemberTypeInfo &Other, llvm::BumpPtrAllocator &Arena);
MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access,
bool IsStatic = false)
: FieldTypeInfo(TI, Name), Access(Access), IsStatic(IsStatic) {}
bool operator==(const MemberTypeInfo &Other) const {
- if (std::tie(Type, Name, Access, IsStatic) !=
- std::tie(Other.Type, Other.Name, Other.Access, Other.IsStatic))
- return false;
- return std::equal(Description.begin(), Description.end(),
- Other.Description.begin(), Other.Description.end());
+ return std::tie(Type, Name, Access, IsStatic, Description) ==
+ std::tie(Other.Type, Other.Name, Other.Access, Other.IsStatic,
+ Other.Description);
}
OwningVec<CommentInfo> Description;
@@ -465,7 +430,7 @@ struct Location : public llvm::ilist_node<Location> {
std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
}
- StringRef Filename = {};
+ StringRef Filename;
int StartLineNumber = 0;
int EndLineNumber = 0;
bool IsFileInRootDir = false;
@@ -477,9 +442,9 @@ struct Info {
StringRef Name = StringRef(), StringRef Path = StringRef())
: Path(internString(Path)), Name(internString(Name)), USR(USR), IT(IT) {}
- Info(const Info &Other, llvm::BumpPtrAllocator &Arena);
Info(const Info &Other) = delete;
Info(Info &&Other) = default;
+ virtual ~Info() = default;
Info &operator=(Info &&Other) = default;
@@ -495,18 +460,18 @@ struct Info {
StringRef getFileBaseName() const;
// Path of directory where the clang-doc generated file will be saved.
- StringRef Path = {};
+ StringRef Path;
// Unqualified name of the decl.
- StringRef Name = {};
+ StringRef Name;
// The name used for the file that this info is documented in.
// In the JSON generator, infos are documented in files with mangled names.
// Thus, we keep track of the physical filename for linking purposes.
- StringRef DocumentationFileName = {};
+ StringRef DocumentationFileName;
// List of parent namespaces for this decl.
- llvm::ArrayRef<Reference> Namespace;
+ llvm::SmallVector<Reference, 4> Namespace;
// Unique identifier for the decl described by this Info.
SymbolID USR = SymbolID();
@@ -519,6 +484,8 @@ struct Info {
// Comment description of this decl.
OwningVec<CommentInfo> Description;
+
+ SmallVector<Context, 4> Contexts;
};
inline Context::Context(const Info &I)
@@ -540,8 +507,6 @@ struct SymbolInfo : public Info {
StringRef Name = StringRef(), StringRef Path = StringRef())
: Info(IT, USR, Name, Path) {}
- SymbolInfo(const SymbolInfo &Other, llvm::BumpPtrAllocator &Arena);
-
void merge(SymbolInfo &&I);
bool operator<(const SymbolInfo &Other) const {
@@ -549,9 +514,8 @@ struct SymbolInfo : public Info {
// generated in the order of the source code.
// If the declaration location is the same, or not present
// we sort by defined location otherwise fallback to the extracted name
- if (Loc.size() > 0 && Other.Loc.size() > 0 &&
- Loc.front() != Other.Loc.front())
- return Loc.front() < Other.Loc.front();
+ if (Loc.size() > 0 && Other.Loc.size() > 0 && Loc[0] != Other.Loc[0])
+ return Loc[0] < Other.Loc[0];
if (DefLoc && Other.DefLoc && *DefLoc != *Other.DefLoc)
return *DefLoc < *Other.DefLoc;
@@ -560,8 +524,8 @@ struct SymbolInfo : public Info {
}
std::optional<Location> DefLoc; // Location where this decl is defined.
- OwningVec<Location> Loc; // Locations where this decl is declared.
- StringRef MangledName = {};
+ llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
+ StringRef MangledName;
bool IsStatic = false;
};
@@ -571,7 +535,6 @@ struct FriendInfo : public SymbolInfo, public llvm::ilist_node<FriendInfo> {
FriendInfo(const InfoType IT, const SymbolID &USR,
const StringRef Name = StringRef())
: SymbolInfo(IT, USR, Name) {}
- FriendInfo(const FriendInfo &Other, llvm::BumpPtrAllocator &Arena);
bool mergeable(const FriendInfo &Other);
void merge(FriendInfo &&Other);
@@ -601,8 +564,8 @@ struct FunctionInfo : public SymbolInfo, public llvm::ilist_node<FunctionInfo> {
Reference Parent;
TypeInfo ReturnType;
- llvm::ArrayRef<FieldTypeInfo> Params;
- StringRef Prototype = {};
+ llvm::SmallVector<FieldTypeInfo, 4> Params;
+ StringRef Prototype;
// When present, this function is a template or specialization.
std::optional<TemplateInfo> Template;
@@ -623,8 +586,6 @@ struct RecordInfo : public SymbolInfo {
RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
StringRef Path = StringRef());
- RecordInfo(const RecordInfo &Other, llvm::BumpPtrAllocator &Arena);
-
void merge(RecordInfo &&I);
// Type of this record (struct, class, union, interface).
@@ -639,18 +600,18 @@ struct RecordInfo : public SymbolInfo {
// When present, this record is a template or specialization.
std::optional<TemplateInfo> Template;
- llvm::ArrayRef<MemberTypeInfo> Members; // List of info about record members.
- llvm::ArrayRef<Reference> Parents; // List of base/parent records
- // (does not include virtual
- // parents).
- llvm::ArrayRef<Reference>
+ llvm::SmallVector<MemberTypeInfo, 4>
+ Members; // List of info about record members.
+ llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
+ // (does not include virtual
+ // parents).
+ llvm::SmallVector<Reference, 4>
VirtualParents; // List of virtual base/parent records.
- llvm::ArrayRef<BaseRecordInfo>
- Bases; // List of base/parent records; this includes
- // inherited methods and attributes
+ OwningVec<BaseRecordInfo> Bases; // List of base/parent records; this includes
+ // inherited methods and attributes
- llvm::ArrayRef<FriendInfo> Friends;
+ OwningVec<FriendInfo> Friends;
ScopeChildren Children;
};
@@ -668,7 +629,7 @@ struct TypedefInfo : public SymbolInfo, public llvm::ilist_node<TypedefInfo> {
std::optional<TemplateInfo> Template;
// Underlying type declaration
- StringRef TypeDeclaration = {};
+ StringRef TypeDeclaration;
// Indicates if this is a new C++ "using"-style typedef:
// using MyVector = std::vector<int>
@@ -677,10 +638,8 @@ struct TypedefInfo : public SymbolInfo, public llvm::ilist_node<TypedefInfo> {
bool IsUsing = false;
};
-struct BaseRecordInfo : public RecordInfo,
- public llvm::ilist_node<BaseRecordInfo> {
+struct BaseRecordInfo : public RecordInfo {
BaseRecordInfo();
- BaseRecordInfo(const BaseRecordInfo &Other, llvm::BumpPtrAllocator &Arena);
BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
AccessSpecifier Access, bool IsParent);
@@ -700,8 +659,6 @@ struct EnumValueInfo {
: Name(internString(Name)), Value(internString(Value)),
ValueExpr(internString(ValueExpr)) {}
- EnumValueInfo(const EnumValueInfo &Other, llvm::BumpPtrAllocator &Arena);
-
bool operator==(const EnumValueInfo &Other) const {
return std::tie(Name, Value, ValueExpr) ==
std::tie(Other.Name, Other.Value, Other.ValueExpr);
@@ -738,7 +695,7 @@ struct EnumInfo : public SymbolInfo, public llvm::ilist_node<EnumInfo> {
// this will be "short".
std::optional<TypeInfo> BaseType;
- llvm::ArrayRef<EnumValueInfo> Members; // List of enum members.
+ llvm::SmallVector<EnumValueInfo, 4> Members; // List of enum members.
};
struct ConceptInfo : public SymbolInfo, public llvm::ilist_node<ConceptInfo> {
@@ -747,9 +704,9 @@ struct ConceptInfo : public SymbolInfo, public llvm::ilist_node<ConceptInfo> {
void merge(ConceptInfo &&I);
- bool IsType = false;
+ bool IsType;
TemplateInfo Template;
- StringRef ConstraintExpression = {};
+ StringRef ConstraintExpression;
};
struct Index : public Reference {
@@ -766,7 +723,7 @@ struct Index : public Reference {
std::optional<StringRef> JumpToSection;
llvm::StringMap<Index> Children;
- std::vector<const Index *> getSortedChildren() const;
+ OwningVec<const Index *> getSortedChildren() const;
void sort();
};
@@ -777,12 +734,6 @@ struct Index : public Reference {
// if they are
diff erent.
llvm::Expected<OwnedPtr<Info>> mergeInfos(OwningPtrArray<Info> &Values);
-// Merges a single new Info into an existing Reduced Info (allocating it if
-// needed).
-llvm::Error mergeSingleInfo(doc::OwnedPtr<doc::Info> &Reduced,
- doc::OwnedPtr<doc::Info> &&NewInfo,
- llvm::BumpPtrAllocator &Arena);
-
struct ClangDocContext {
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
@@ -822,26 +773,28 @@ struct ClangDocContext {
// Ensure arena allocated types remain safe to allocate in the arena.
// Only trivially destructible types are safe, so enforce that at compile-time.
static_assert(std::is_trivially_destructible_v<CommentInfo>);
-static_assert(std::is_trivially_destructible_v<ConceptInfo>);
static_assert(std::is_trivially_destructible_v<ConstraintInfo>);
-static_assert(std::is_trivially_destructible_v<EnumInfo>);
static_assert(std::is_trivially_destructible_v<FieldTypeInfo>);
-static_assert(std::is_trivially_destructible_v<FriendInfo>);
-static_assert(std::is_trivially_destructible_v<FunctionInfo>);
-static_assert(std::is_trivially_destructible_v<Info>);
static_assert(std::is_trivially_destructible_v<Location>);
-static_assert(std::is_trivially_destructible_v<MemberTypeInfo>);
-static_assert(std::is_trivially_destructible_v<NamespaceInfo>);
-static_assert(std::is_trivially_destructible_v<RecordInfo>);
static_assert(std::is_trivially_destructible_v<Reference>);
-static_assert(std::is_trivially_destructible_v<ScopeChildren>);
-static_assert(std::is_trivially_destructible_v<SymbolInfo>);
-static_assert(std::is_trivially_destructible_v<TemplateInfo>);
static_assert(std::is_trivially_destructible_v<TemplateParamInfo>);
-static_assert(std::is_trivially_destructible_v<TemplateSpecializationInfo>);
static_assert(std::is_trivially_destructible_v<TypeInfo>);
-static_assert(std::is_trivially_destructible_v<TypedefInfo>);
-static_assert(std::is_trivially_destructible_v<VarInfo>);
+
+// FIXME: These types need to be trivially destructible for arena allocation.
+static_assert(!std::is_trivially_destructible_v<ConceptInfo>);
+static_assert(!std::is_trivially_destructible_v<EnumInfo>);
+static_assert(!std::is_trivially_destructible_v<FriendInfo>);
+static_assert(!std::is_trivially_destructible_v<FunctionInfo>);
+static_assert(!std::is_trivially_destructible_v<Info>);
+static_assert(!std::is_trivially_destructible_v<MemberTypeInfo>);
+static_assert(!std::is_trivially_destructible_v<NamespaceInfo>);
+static_assert(!std::is_trivially_destructible_v<RecordInfo>);
+static_assert(!std::is_trivially_destructible_v<ScopeChildren>);
+static_assert(!std::is_trivially_destructible_v<SymbolInfo>);
+static_assert(!std::is_trivially_destructible_v<TemplateInfo>);
+static_assert(!std::is_trivially_destructible_v<TemplateSpecializationInfo>);
+static_assert(!std::is_trivially_destructible_v<TypedefInfo>);
+static_assert(!std::is_trivially_destructible_v<VarInfo>);
} // namespace doc
} // namespace clang
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 4b2f0b5eac3a4..ef7fed6cc8501 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -182,8 +182,8 @@ StringRef Serializer::getTypeAlias(const TypeAliasDecl *Alias) {
//
// }
// }
-StringRef
-Serializer::getInfoRelativePath(llvm::ArrayRef<doc::Reference> Namespaces) {
+StringRef Serializer::getInfoRelativePath(
+ const llvm::SmallVectorImpl<doc::Reference> &Namespaces) {
llvm::SmallString<128> Path;
for (auto R = Namespaces.rbegin(), E = Namespaces.rend(); R != E; ++R)
llvm::sys::path::append(Path, R->Name);
@@ -258,7 +258,9 @@ void ClangDocCommentVisitor::visitInlineCommandComment(
for (unsigned I = 0, E = C->getNumArgs(); I != E; ++I)
Args.push_back(internString(C->getArgText(I).trim()));
if (!Args.empty()) {
- CurrentCI.Args = allocateArray(Args, TransientArena);
+ StringRef *ArgsMem = TransientArena.Allocate<StringRef>(Args.size());
+ std::uninitialized_copy(Args.begin(), Args.end(), ArgsMem);
+ CurrentCI.Args = llvm::ArrayRef<StringRef>(ArgsMem, Args.size());
}
}
@@ -274,10 +276,16 @@ void ClangDocCommentVisitor::visitHTMLStartTagComment(
AttrValues.push_back(internString(Attr.Value));
}
if (!AttrKeys.empty()) {
- CurrentCI.AttrKeys = allocateArray(AttrKeys, TransientArena);
+ StringRef *KeysMem = TransientArena.Allocate<StringRef>(AttrKeys.size());
+ std::uninitialized_copy(AttrKeys.begin(), AttrKeys.end(), KeysMem);
+ CurrentCI.AttrKeys = llvm::ArrayRef<StringRef>(KeysMem, AttrKeys.size());
}
if (!AttrValues.empty()) {
- CurrentCI.AttrValues = allocateArray(AttrValues, TransientArena);
+ StringRef *ValuesMem =
+ TransientArena.Allocate<StringRef>(AttrValues.size());
+ std::uninitialized_copy(AttrValues.begin(), AttrValues.end(), ValuesMem);
+ CurrentCI.AttrValues =
+ llvm::ArrayRef<StringRef>(ValuesMem, AttrValues.size());
}
}
@@ -294,7 +302,9 @@ void ClangDocCommentVisitor::visitBlockCommandComment(
for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
Args.push_back(internString(C->getArgText(I).trim()));
if (!Args.empty()) {
- CurrentCI.Args = allocateArray(Args, TransientArena);
+ StringRef *ArgsMem = TransientArena.Allocate<StringRef>(Args.size());
+ std::uninitialized_copy(Args.begin(), Args.end(), ArgsMem);
+ CurrentCI.Args = llvm::ArrayRef<StringRef>(ArgsMem, Args.size());
}
}
@@ -465,35 +475,29 @@ void Serializer::InsertChild(ScopeChildren &Scope, const NamespaceInfo &Info) {
}
void Serializer::InsertChild(ScopeChildren &Scope, const RecordInfo &Info) {
- Reference *R = allocatePtr<Reference>(
- Info.USR, Info.Name, InfoType::IT_record, Info.Name,
- getInfoRelativePath(Info.Namespace), Info.MangledName);
- Scope.Records.push_back(*R);
+ Scope.Records.emplace_back(Info.USR, Info.Name, InfoType::IT_record,
+ Info.Name, getInfoRelativePath(Info.Namespace),
+ Info.MangledName);
}
void Serializer::InsertChild(ScopeChildren &Scope, EnumInfo Info) {
- EnumInfo *E = allocatePtr<EnumInfo>(std::move(Info));
- Scope.Enums.push_back(*E);
+ Scope.Enums.push_back(std::move(Info));
}
void Serializer::InsertChild(ScopeChildren &Scope, FunctionInfo Info) {
- FunctionInfo *F = allocatePtr<FunctionInfo>(std::move(Info));
- Scope.Functions.push_back(*F);
+ Scope.Functions.push_back(std::move(Info));
}
void Serializer::InsertChild(ScopeChildren &Scope, TypedefInfo Info) {
- TypedefInfo *T = allocatePtr<TypedefInfo>(std::move(Info));
- Scope.Typedefs.push_back(*T);
+ Scope.Typedefs.push_back(std::move(Info));
}
void Serializer::InsertChild(ScopeChildren &Scope, ConceptInfo Info) {
- ConceptInfo *C = allocatePtr<ConceptInfo>(std::move(Info));
- Scope.Concepts.push_back(*C);
+ Scope.Concepts.push_back(std::move(Info));
}
void Serializer::InsertChild(ScopeChildren &Scope, VarInfo Info) {
- VarInfo *V = allocatePtr<VarInfo>(std::move(Info));
- Scope.Variables.push_back(*V);
+ Scope.Variables.push_back(std::move(Info));
}
// Creates a parent of the correct type for the given child and inserts it into
@@ -577,18 +581,14 @@ AccessSpecifier Serializer::getFinalAccessSpecifier(AccessSpecifier FirstAS,
// record, the access specification of the field depends on the inheritance mode
void Serializer::parseFields(RecordInfo &I, const RecordDecl *D,
bool PublicOnly, AccessSpecifier Access) {
- SmallVector<MemberTypeInfo, 4> Members;
for (const FieldDecl *F : D->fields()) {
if (!shouldSerializeInfo(PublicOnly, /*IsInAnonymousNamespace=*/false, F))
continue;
- populateMemberTypeInfo(Members, Access, F);
+ populateMemberTypeInfo(I, Access, F);
}
const auto *CxxRD = dyn_cast<CXXRecordDecl>(D);
- if (!CxxRD) {
- if (!Members.empty())
- I.Members = allocateArray<MemberTypeInfo>(Members, TransientArena);
+ if (!CxxRD)
return;
- }
for (Decl *CxxDecl : CxxRD->decls()) {
auto *VD = dyn_cast<VarDecl>(CxxDecl);
if (!VD ||
@@ -596,49 +596,40 @@ void Serializer::parseFields(RecordInfo &I, const RecordDecl *D,
continue;
if (VD->isStaticDataMember())
- populateMemberTypeInfo(Members, Access, VD, /*IsStatic=*/true);
+ populateMemberTypeInfo(I, Access, VD, /*IsStatic=*/true);
}
- if (!Members.empty())
- I.Members = allocateArray<MemberTypeInfo>(Members, TransientArena);
}
void Serializer::parseEnumerators(EnumInfo &I, const EnumDecl *D) {
- llvm::SmallVector<EnumValueInfo, 4> LocalMembers;
for (const EnumConstantDecl *E : D->enumerators()) {
std::string ValueExpr;
if (const Expr *InitExpr = E->getInitExpr())
ValueExpr = getSourceCode(D, InitExpr->getSourceRange());
SmallString<16> ValueStr;
E->getInitVal().toString(ValueStr);
- EnumValueInfo &Member = LocalMembers.emplace_back(
- E->getNameAsString(), ValueStr.str(), ValueExpr);
+ I.Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
ASTContext &Context = E->getASTContext();
if (RawComment *Comment =
E->getASTContext().getRawCommentForDeclNoCache(E)) {
Comment->setAttached();
if (comments::FullComment *Fc = Comment->parse(Context, nullptr, E)) {
- CommentInfo *NewCI = allocatePtr<CommentInfo>();
- Member.Description.push_back(*NewCI);
+ EnumValueInfo &Member = I.Members.back();
+ Member.Description.emplace_back();
parseFullComment(Fc, Member.Description.back());
}
}
}
- if (!LocalMembers.empty())
- I.Members = allocateArray<EnumValueInfo>(LocalMembers, TransientArena);
}
void Serializer::parseParameters(FunctionInfo &I, const FunctionDecl *D) {
- llvm::SmallVector<FieldTypeInfo, 4> LocalParams;
auto &LO = D->getLangOpts();
for (const ParmVarDecl *P : D->parameters()) {
- FieldTypeInfo &FieldInfo = LocalParams.emplace_back(
+ FieldTypeInfo &FieldInfo = I.Params.emplace_back(
getTypeInfoForType(P->getOriginalType(), LO), P->getNameAsString());
if (std::optional<StringRef> DefaultValue =
getSourceCode(D, P->getDefaultArgRange()))
FieldInfo.DefaultValue = *DefaultValue;
}
- if (!LocalParams.empty())
- I.Params = allocateArray<FieldTypeInfo>(LocalParams, TransientArena);
}
// TODO: Remove the serialization of Parents and VirtualParents, this
@@ -648,36 +639,28 @@ void Serializer::parseBases(RecordInfo &I, const CXXRecordDecl *D) {
if (!D->isThisDeclarationADefinition())
return;
- llvm::SmallVector<Reference, 4> LocalParents;
for (const CXXBaseSpecifier &B : D->bases()) {
if (B.isVirtual())
continue;
if (const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
- LocalParents.emplace_back(getUSRForDecl(D), B.getType().getAsString(),
- InfoType::IT_record, B.getType().getAsString());
+ I.Parents.emplace_back(getUSRForDecl(D), B.getType().getAsString(),
+ InfoType::IT_record, B.getType().getAsString());
} else if (const RecordDecl *P = getRecordDeclForType(B.getType()))
- LocalParents.emplace_back(
- getUSRForDecl(P), P->getNameAsString(), InfoType::IT_record,
- P->getQualifiedNameAsString(), internString(getInfoRelativePath(P)));
+ I.Parents.emplace_back(getUSRForDecl(P), P->getNameAsString(),
+ InfoType::IT_record, P->getQualifiedNameAsString(),
+ internString(getInfoRelativePath(P)));
else
- LocalParents.emplace_back(SymbolID(), B.getType().getAsString());
+ I.Parents.emplace_back(SymbolID(), B.getType().getAsString());
}
- if (!LocalParents.empty())
- I.Parents = allocateArray<Reference>(LocalParents, TransientArena);
-
- llvm::SmallVector<Reference, 4> LocalVirtualParents;
for (const CXXBaseSpecifier &B : D->vbases()) {
if (const RecordDecl *P = getRecordDeclForType(B.getType()))
- LocalVirtualParents.emplace_back(
+ I.VirtualParents.emplace_back(
getUSRForDecl(P), P->getNameAsString(), InfoType::IT_record,
P->getQualifiedNameAsString(), internString(getInfoRelativePath(P)));
else
- LocalVirtualParents.emplace_back(SymbolID(), B.getType().getAsString());
+ I.VirtualParents.emplace_back(SymbolID(), B.getType().getAsString());
}
- if (!LocalVirtualParents.empty())
- I.VirtualParents =
- allocateArray<Reference>(LocalVirtualParents, TransientArena);
}
template <typename T>
@@ -725,13 +708,10 @@ void Serializer::populateTemplateParameters(
if (!TemplateInfo) {
TemplateInfo.emplace();
}
- llvm::SmallVector<TemplateParamInfo, 4> LocalParams;
for (const NamedDecl *ND : *ParamList) {
- LocalParams.emplace_back(getSourceCode(ND, ND->getSourceRange()));
+ TemplateInfo->Params.emplace_back(
+ getSourceCode(ND, ND->getSourceRange()));
}
- if (!LocalParams.empty())
- TemplateInfo->Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
}
}
@@ -794,14 +774,9 @@ void Serializer::populateInfo(Info &I, const T *D, const FullComment *C,
ConversionDecl->getConversionType().getAsString());
else
I.Name = internString(D->getNameAsString());
- llvm::SmallVector<Reference, 4> LocalNamespaces;
- populateParentNamespaces(LocalNamespaces, D, IsInAnonymousNamespace);
- if (!LocalNamespaces.empty())
- I.Namespace = allocateArray<Reference>(LocalNamespaces, TransientArena);
+ populateParentNamespaces(I.Namespace, D, IsInAnonymousNamespace);
if (C) {
-
- CommentInfo *NewCI = allocatePtr<CommentInfo>();
- I.Description.push_back(*NewCI);
+ I.Description.emplace_back();
parseFullComment(C, I.Description.back());
}
}
@@ -813,10 +788,8 @@ void Serializer::populateSymbolInfo(SymbolInfo &I, const T *D,
populateInfo(I, D, C, IsInAnonymousNamespace);
if (D->isThisDeclarationADefinition())
I.DefLoc = Loc;
- else {
- Location *NewL = allocatePtr<Location>(Loc);
- I.Loc.push_back(*NewL);
- }
+ else
+ I.Loc.emplace_back(Loc);
auto *Mangler = ItaniumMangleContext::create(
D->getASTContext(), D->getASTContext().getDiagnostics());
@@ -838,8 +811,7 @@ void Serializer::populateSymbolInfo(SymbolInfo &I, const T *D,
}
void Serializer::handleCompoundConstraints(
- const Expr *Constraint,
- llvm::SmallVectorImpl<ConstraintInfo> &ConstraintInfos) {
+ const Expr *Constraint, OwningVec<ConstraintInfo> &ConstraintInfos) {
if (Constraint->getStmtClass() == Stmt::ParenExprClass) {
handleCompoundConstraints(dyn_cast<ParenExpr>(Constraint)->getSubExpr(),
ConstraintInfos);
@@ -863,7 +835,6 @@ void Serializer::populateConstraints(TemplateInfo &I, const TemplateDecl *D) {
SmallVector<AssociatedConstraint> AssociatedConstraints;
D->getAssociatedConstraints(AssociatedConstraints);
- SmallVector<ConstraintInfo, 4> LocalConstraints;
for (const auto &Constraint : AssociatedConstraints) {
if (!Constraint)
continue;
@@ -875,14 +846,11 @@ void Serializer::populateConstraints(TemplateInfo &I, const TemplateDecl *D) {
ConstraintInfo CI(getUSRForDecl(ConstraintExpr->getNamedConcept()),
ConstraintExpr->getNamedConcept()->getNameAsString());
CI.ConstraintExpr = internString(exprToString(ConstraintExpr));
- LocalConstraints.push_back(std::move(CI));
+ I.Constraints.push_back(std::move(CI));
} else {
- handleCompoundConstraints(Constraint.ConstraintExpr, LocalConstraints);
+ handleCompoundConstraints(Constraint.ConstraintExpr, I.Constraints);
}
}
- if (!LocalConstraints.empty())
- I.Constraints =
- allocateArray<ConstraintInfo>(LocalConstraints, TransientArena);
}
void Serializer::populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
@@ -911,13 +879,9 @@ void Serializer::populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
// Template parameters to the specialization.
if (FTSI->TemplateArguments) {
- SmallVector<TemplateParamInfo, 4> LocalParams;
for (const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
- LocalParams.push_back(convertTemplateArgToInfo(D, Arg));
+ Specialization.Params.push_back(convertTemplateArgToInfo(D, Arg));
}
- if (!LocalParams.empty())
- Specialization.Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
}
}
}
@@ -937,28 +901,26 @@ void Serializer::populateMemberTypeInfo(T &I, const Decl *D) {
Comment->setAttached();
if (comments::FullComment *Fc = Comment->parse(Context, nullptr, D)) {
- CommentInfo *NewCI = allocatePtr<CommentInfo>();
- I.Description.push_back(*NewCI);
+ I.Description.emplace_back();
parseFullComment(Fc, I.Description.back());
}
}
-void Serializer::populateMemberTypeInfo(
- SmallVectorImpl<MemberTypeInfo> &Members, AccessSpecifier &Access,
- const DeclaratorDecl *D, bool IsStatic) {
+void Serializer::populateMemberTypeInfo(RecordInfo &I, AccessSpecifier &Access,
+ const DeclaratorDecl *D,
+ bool IsStatic) {
// Use getAccessUnsafe so that we just get the default AS_none if it's not
// valid, as opposed to an assert.
- MemberTypeInfo &NewMember = Members.emplace_back(
+ MemberTypeInfo &NewMember = I.Members.emplace_back(
getTypeInfoForType(D->getTypeSourceInfo()->getType(), D->getLangOpts()),
D->getNameAsString(),
getFinalAccessSpecifier(Access, D->getAccessUnsafe()), IsStatic);
populateMemberTypeInfo(NewMember, D);
}
-void Serializer::parseBases(llvm::SmallVectorImpl<BaseRecordInfo> &Bases,
- const CXXRecordDecl *D, bool IsFileInRootDir,
- bool PublicOnly, bool IsParent,
- AccessSpecifier ParentAccess) {
+void Serializer::parseBases(RecordInfo &I, const CXXRecordDecl *D,
+ bool IsFileInRootDir, bool PublicOnly,
+ bool IsParent, AccessSpecifier ParentAccess) {
// Don't parse bases if this isn't a definition.
if (!D->isThisDeclarationADefinition())
return;
@@ -997,15 +959,14 @@ void Serializer::parseBases(llvm::SmallVectorImpl<BaseRecordInfo> &Bases,
IsInAnonymousNamespace);
FI.Access =
getFinalAccessSpecifier(BI.Access, MD->getAccessUnsafe());
- FunctionInfo *FIPtr = allocatePtr<FunctionInfo>(std::move(FI));
- BI.Children.Functions.push_back(*FIPtr);
+ BI.Children.Functions.emplace_back(std::move(FI));
}
- Bases.emplace_back(std::move(BI));
+ I.Bases.emplace_back(std::move(BI));
// Call this function recursively to get the inherited classes of
// this base; these new bases will also get stored in the original
// RecordInfo: I.
- parseBases(Bases, Base, IsFileInRootDir, PublicOnly, false,
- Bases.back().Access);
+ parseBases(I, Base, IsFileInRootDir, PublicOnly, false,
+ I.Bases.back().Access);
}
}
}
@@ -1034,8 +995,6 @@ void Serializer::parseFriends(RecordInfo &RI, const CXXRecordDecl *D) {
if (!D->hasDefinition() || !D->hasFriends())
return;
- llvm::SmallVector<FriendInfo, 4> LocalFriends;
-
for (const FriendDecl *FD : D->friends()) {
if (FD->isUnsupportedFriend())
continue;
@@ -1057,12 +1016,9 @@ void Serializer::parseFriends(RecordInfo &RI, const CXXRecordDecl *D) {
if (isa<RecordDecl>(ActualTD->getTemplatedDecl()))
F.IsClass = true;
F.Template.emplace();
- llvm::SmallVector<TemplateParamInfo, 4> LocalParams;
for (const auto *Param : ActualTD->getTemplateParameters()->asArray())
- LocalParams.emplace_back(getSourceCode(Param, Param->getSourceRange()));
- if (!LocalParams.empty())
- F.Template->Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
+ F.Template->Params.emplace_back(
+ getSourceCode(Param, Param->getSourceRange()));
ActualDecl = ActualTD->getTemplatedDecl();
}
@@ -1080,10 +1036,8 @@ void Serializer::parseFriends(RecordInfo &RI, const CXXRecordDecl *D) {
getInfoRelativePath(ActualDecl));
populateMemberTypeInfo(F, ActualDecl);
- LocalFriends.push_back(std::move(F));
+ RI.Friends.push_back(std::move(F));
}
- if (!LocalFriends.empty())
- RI.Friends = allocateArray<FriendInfo>(LocalFriends, TransientArena);
}
std::pair<OwnedPtr<Info>, OwnedPtr<Info>>
@@ -1107,11 +1061,7 @@ Serializer::emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
}
// TODO: remove first call to parseBases, that function should be deleted
parseBases(*RI, C);
- llvm::SmallVector<BaseRecordInfo, 4> LocalBases;
- parseBases(LocalBases, C, /*IsFileInRootDir=*/true, PublicOnly,
- /*IsParent=*/true);
- if (!LocalBases.empty())
- RI->Bases = allocateArray<BaseRecordInfo>(LocalBases, TransientArena);
+ parseBases(*RI, C, /*IsFileInRootDir=*/true, PublicOnly, /*IsParent=*/true);
parseFriends(*RI, C);
}
RI->Path = internString(getInfoRelativePath(RI->Namespace));
@@ -1144,23 +1094,15 @@ Serializer::emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
if (const ASTTemplateArgumentListInfo *AsWritten =
CTPSD->getTemplateArgsAsWritten()) {
- llvm::SmallVector<TemplateParamInfo, 4> LocalParams;
for (unsigned Idx = 0; Idx < AsWritten->getNumTemplateArgs(); Idx++) {
- LocalParams.emplace_back(
+ Specialization.Params.emplace_back(
getSourceCode(D, (*AsWritten)[Idx].getSourceRange()));
}
- if (!LocalParams.empty())
- Specialization.Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
}
} else {
- llvm::SmallVector<TemplateParamInfo, 4> LocalParams;
for (const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
- LocalParams.push_back(convertTemplateArgToInfo(D, Arg));
+ Specialization.Params.push_back(convertTemplateArgToInfo(D, Arg));
}
- if (!LocalParams.empty())
- Specialization.Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
}
}
@@ -1222,9 +1164,8 @@ void Serializer::extractCommentFromDecl(const Decl *D, TypedefInfo &Info) {
Comment->setAttached();
if (comments::FullComment *Fc = Comment->parse(Context, nullptr, D)) {
- CommentInfo *NewCI = allocatePtr<CommentInfo>();
- Info.Description.push_back(*NewCI);
- parseFullComment(Fc, *NewCI);
+ Info.Description.emplace_back();
+ parseFullComment(Fc, Info.Description.back());
}
}
@@ -1317,13 +1258,10 @@ Serializer::emitInfo(const ConceptDecl *D, const FullComment *FC,
Concept.ConstraintExpression = exprToString(D->getConstraintExpr());
if (auto *ConceptParams = D->getTemplateParameters()) {
- llvm::SmallVector<TemplateParamInfo, 4> LocalParams;
for (const auto *Param : ConceptParams->asArray()) {
- LocalParams.emplace_back(getSourceCode(Param, Param->getSourceRange()));
+ Concept.Template.Params.emplace_back(
+ getSourceCode(Param, Param->getSourceRange()));
}
- if (!LocalParams.empty())
- Concept.Template.Params =
- allocateArray<TemplateParamInfo>(LocalParams, TransientArena);
}
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
diff --git a/clang-tools-extra/clang-doc/Serialize.h b/clang-tools-extra/clang-doc/Serialize.h
index 3d53514d0756a..04891bea33220 100644
--- a/clang-tools-extra/clang-doc/Serialize.h
+++ b/clang-tools-extra/clang-doc/Serialize.h
@@ -94,7 +94,8 @@ class Serializer {
StringRef getTypeAlias(const TypeAliasDecl *Alias);
- StringRef getInfoRelativePath(llvm::ArrayRef<doc::Reference> Namespaces);
+ StringRef
+ getInfoRelativePath(const llvm::SmallVectorImpl<doc::Reference> &Namespaces);
StringRef getInfoRelativePath(const Decl *D);
@@ -138,9 +139,8 @@ class Serializer {
void parseBases(RecordInfo &I, const CXXRecordDecl *D);
- void parseBases(llvm::SmallVectorImpl<BaseRecordInfo> &Bases,
- const CXXRecordDecl *D, bool IsFileInRootDir, bool PublicOnly,
- bool IsParent,
+ void parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
+ bool PublicOnly, bool IsParent,
AccessSpecifier ParentAccess = AccessSpecifier::AS_public);
template <typename T>
@@ -165,9 +165,8 @@ class Serializer {
void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
Location Loc, bool &IsInAnonymousNamespace);
- void handleCompoundConstraints(
- const Expr *Constraint,
- llvm::SmallVectorImpl<ConstraintInfo> &ConstraintInfos);
+ void handleCompoundConstraints(const Expr *Constraint,
+ OwningVec<ConstraintInfo> &ConstraintInfos);
void populateConstraints(TemplateInfo &I, const TemplateDecl *D);
@@ -177,9 +176,8 @@ class Serializer {
template <typename T> void populateMemberTypeInfo(T &I, const Decl *D);
- void populateMemberTypeInfo(llvm::SmallVectorImpl<MemberTypeInfo> &Members,
- AccessSpecifier &Access, const DeclaratorDecl *D,
- bool IsStatic = false);
+ void populateMemberTypeInfo(RecordInfo &I, AccessSpecifier &Access,
+ const DeclaratorDecl *D, bool IsStatic = false);
void parseFriends(RecordInfo &RI, const CXXRecordDecl *D);
diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
index b5c43837f9505..9e3bca84877e0 100644
--- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -31,70 +31,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(BaseRecordInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(OwnedPtr<CommentInfo>)
namespace llvm {
-
-template <typename T>
-bool operator==(const llvm::simple_ilist<T> &LHS,
- const llvm::simple_ilist<T> &RHS) {
- auto LIt = LHS.begin(), LEnd = LHS.end();
- auto RIt = RHS.begin(), REnd = RHS.end();
- for (; LIt != LEnd && RIt != REnd; ++LIt, ++RIt) {
- if (!(*LIt == *RIt))
- return false;
- }
- return LIt == LEnd && RIt == REnd;
-}
-
-template <typename T>
-bool operator!=(const llvm::simple_ilist<T> &LHS,
- const llvm::simple_ilist<T> &RHS) {
- return !(LHS == RHS);
-}
-
namespace yaml {
-// Provide SequenceTraits for ArrayRef<T*> since YAMLTraits only provides it for
-// MutableArrayRef
-template <typename T> struct SequenceTraits<ArrayRef<T *>> {
- static size_t size(IO &io, ArrayRef<T *> &seq) { return seq.size(); }
- static T *&element(IO &io, ArrayRef<T *> &seq, size_t index) {
- // ArrayRef is not mutable, but YAML output only reads the value.
- return const_cast<T *&>(seq[index]);
- }
-};
-
-template <typename T> struct SequenceTraits<llvm::simple_ilist<T>> {
- static size_t size(IO &io, llvm::simple_ilist<T> &seq) { return seq.size(); }
- static T &element(IO &io, llvm::simple_ilist<T> &seq, size_t index) {
- return *std::next(seq.begin(), index);
- }
-};
-
-// Map pointers to the value mappings as clang-doc only does output
-// serialization.
-template <typename T> struct PointerMappingTraits {
- static void mapping(IO &IO, T *&Val) {
- if (Val)
- MappingTraits<T>::mapping(IO, *Val);
- }
-};
-
-template <>
-struct MappingTraits<clang::doc::Reference *>
- : PointerMappingTraits<clang::doc::Reference> {};
-template <>
-struct MappingTraits<clang::doc::CommentInfo *>
- : PointerMappingTraits<clang::doc::CommentInfo> {};
-template <>
-struct MappingTraits<clang::doc::FunctionInfo *>
- : PointerMappingTraits<clang::doc::FunctionInfo> {};
-template <>
-struct MappingTraits<clang::doc::EnumInfo *>
- : PointerMappingTraits<clang::doc::EnumInfo> {};
-template <>
-struct MappingTraits<clang::doc::TemplateParamInfo *>
- : PointerMappingTraits<clang::doc::TemplateParamInfo> {};
-
-template <typename T> struct SequenceTraits<ArrayRef<T>> {
+template <typename T> struct SequenceTraits<llvm::ArrayRef<T>> {
static size_t size(IO &io, llvm::ArrayRef<T> &seq) { return seq.size(); }
static T &element(IO &io, llvm::ArrayRef<T> &seq, size_t index) {
return const_cast<T &>(seq[index]);
@@ -252,7 +191,7 @@ static void infoMapping(IO &IO, Info &I) {
static void symbolInfoMapping(IO &IO, SymbolInfo &I) {
infoMapping(IO, I);
IO.mapOptional("DefLocation", I.DefLoc, std::optional<Location>());
- IO.mapOptional("Location", I.Loc);
+ IO.mapOptional("Location", I.Loc, llvm::SmallVector<Location, 2>());
}
static void recordInfoMapping(IO &IO, RecordInfo &I) {
@@ -261,10 +200,10 @@ static void recordInfoMapping(IO &IO, RecordInfo &I) {
IO.mapOptional("IsTypeDef", I.IsTypeDef, false);
IO.mapOptional("Members", I.Members);
IO.mapOptional("Bases", I.Bases);
- IO.mapOptional("Parents", I.Parents, SmallVector<Reference, 4>());
+ IO.mapOptional("Parents", I.Parents, llvm::SmallVector<Reference, 4>());
IO.mapOptional("VirtualParents", I.VirtualParents,
llvm::SmallVector<Reference, 4>());
- IO.mapOptional("ChildRecords", I.Children.Records);
+ IO.mapOptional("ChildRecords", I.Children.Records, OwningVec<Reference>());
IO.mapOptional("ChildFunctions", I.Children.Functions);
IO.mapOptional("ChildEnums", I.Children.Enums);
IO.mapOptional("ChildTypedefs", I.Children.Typedefs);
@@ -400,7 +339,7 @@ template <> struct MappingTraits<NamespaceInfo> {
for (const auto &N : I.Children.Namespaces)
TempNamespaces.push_back(N);
IO.mapOptional("ChildNamespaces", TempNamespaces, std::vector<Reference>());
- IO.mapOptional("ChildRecords", I.Children.Records);
+ IO.mapOptional("ChildRecords", I.Children.Records, OwningVec<Reference>());
IO.mapOptional("ChildFunctions", I.Children.Functions);
IO.mapOptional("ChildEnums", I.Children.Enums);
IO.mapOptional("ChildTypedefs", I.Children.Typedefs);
@@ -502,6 +441,13 @@ template <> struct MappingTraits<CommentInfo> {
static void mapping(IO &IO, CommentInfo &I) { commentInfoMapping(IO, I); }
};
+template <> struct MappingTraits<OwnedPtr<CommentInfo>> {
+ static void mapping(IO &IO, OwnedPtr<CommentInfo> &I) {
+ if (I)
+ commentInfoMapping(IO, *I);
+ }
+};
+
} // end namespace yaml
} // end namespace llvm
diff --git a/clang-tools-extra/clang-doc/benchmarks/ClangDocBenchmark.cpp b/clang-tools-extra/clang-doc/benchmarks/ClangDocBenchmark.cpp
index c610c57722649..f96cfc9426f1a 100644
--- a/clang-tools-extra/clang-doc/benchmarks/ClangDocBenchmark.cpp
+++ b/clang-tools-extra/clang-doc/benchmarks/ClangDocBenchmark.cpp
@@ -184,10 +184,9 @@ static void BM_JSONGenerator_Scale(benchmark::State &State) {
auto NI = allocatePtr<NamespaceInfo>();
NI->Name = "GlobalNamespace";
for (int i = 0; i < NumRecords; ++i) {
- Reference *R = new (TransientArena.Allocate<Reference>())
- Reference(SymbolID{(uint8_t)(i & 0xFF)}, "Record" + std::to_string(i),
- InfoType::IT_record);
- NI->Children.Records.push_back(*R);
+ NI->Children.Records.emplace_back(SymbolID{(uint8_t)(i & 0xFF)},
+ "Record" + std::to_string(i),
+ InfoType::IT_record);
}
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 3c38901f4a0f9..f627ee5887528 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -29,7 +29,6 @@
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Execution.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
@@ -359,22 +358,15 @@ Example usage for a project using a compile commands database:
llvm::hardware_concurrency(ExecutorConcurrency));
{
llvm::TimeTraceScope TS("Reduce");
- for (const auto &Group : USRToBitcode) {
- StringRef Key = Group.getKey();
- std::vector<StringRef> Bitcodes = Group.getValue();
- Pool.async([Key, Bitcodes, &CDCtx, &Diags, &USRToInfo, &USRToInfoMutex,
- &IndexMutex, &DiagMutex, &Error, DiagIDBitcodeReading,
- DiagIDBitcodeMerging]() {
- if (CDCtx.FTimeTrace)
+ for (auto &Group : USRToBitcode) {
+ Pool.async([&, &Diags = Diags]() { // time trace decoding bitcode
+ if (FTimeTrace)
llvm::timeTraceProfilerInitialize(200, "clang-doc");
- doc::OwnedPtr<doc::Info> Reduced = nullptr;
+ doc::OwningPtrVec<doc::Info> Infos;
{
- llvm::TimeTraceScope Red("decoding and merging bitcode");
- for (const auto &Bitcode : Bitcodes) {
-
- llvm::scope_exit ArenaGuard(
- [] { clang::doc::TransientArena.Reset(); });
+ llvm::TimeTraceScope Red("decoding bitcode");
+ for (auto &Bitcode : Group.getValue()) {
llvm::BitstreamCursor Stream(Bitcode);
doc::ClangDocBitcodeReader Reader(Stream, Diags);
auto ReadInfos = Reader.readBitcode();
@@ -386,17 +378,25 @@ Example usage for a project using a compile commands database:
Error = true;
return;
}
- for (auto &I : *ReadInfos) {
- if (auto Err = doc::mergeSingleInfo(
- Reduced, std::move(I), clang::doc::PersistentArena)) {
- std::lock_guard<llvm::sys::Mutex> Guard(DiagMutex);
- Diags.Report(DiagIDBitcodeMerging)
- << toString(std::move(Err));
- return;
- }
- }
+ std::move(ReadInfos->begin(), ReadInfos->end(),
+ std::back_inserter(Infos));
+ }
+ } // time trace decoding bitcode
+
+ doc::OwnedPtr<doc::Info> Reduced;
+
+ {
+ llvm::TimeTraceScope Merge("merging bitcode");
+ auto ExpReduced = doc::mergeInfos(Infos);
+
+ if (!ExpReduced) {
+ std::lock_guard<llvm::sys::Mutex> Guard(DiagMutex);
+ Diags.Report(DiagIDBitcodeMerging)
+ << toString(ExpReduced.takeError());
+ return;
}
- } // time trace decoding and merging bitcode
+ Reduced = std::move(*ExpReduced);
+ } // time trace merging bitcode
// Add a reference to this Info in the Index
{
@@ -408,7 +408,7 @@ Example usage for a project using a compile commands database:
{
llvm::TimeTraceScope Merge("USRToInfo");
std::lock_guard<llvm::sys::Mutex> Guard(USRToInfoMutex);
- USRToInfo[Key] = std::move(Reduced);
+ USRToInfo[Group.getKey()] = std::move(Reduced);
}
if (CDCtx.FTimeTrace)
diff --git a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
index 81de4ff2f6381..6bdf538012303 100644
--- a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp
@@ -56,6 +56,7 @@ static OwningPtrVec<Info> readInfo(StringRef Bitcode, size_t NumInfos,
llvm::BitstreamCursor Stream(Bitcode);
doc::ClangDocBitcodeReader Reader(Stream, Diags);
auto Infos = Reader.readBitcode();
+
// Check that there was no error in the read.
assert(Infos);
EXPECT_EQ(Infos.get().size(), NumInfos);
@@ -67,43 +68,39 @@ class BitcodeTest : public ClangDocContextTest {};
TEST_F(BitcodeTest, emitNamespaceInfoBitcode) {
NamespaceInfo I;
I.Name = "r";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace);
I.Children.Namespaces.push_back(NewNamespace);
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record);
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo FI;
- I.Children.Functions.push_back(FI);
- EnumInfo EI;
- I.Children.Enums.push_back(EI);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+ I.Children.Functions.emplace_back();
+ I.Children.Enums.emplace_back();
std::string WriteResult = writeInfo(&I, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckNamespaceInfo(&I, InfoAsNamespace(ReadResults[0]));
+ CheckNamespaceInfo(&I, InfoAsNamespace(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitRecordInfoBitcode) {
RecordInfo I;
I.Name = "r";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- MemberTypeInfo M(TypeInfo("int"), "X", AccessSpecifier::AS_private);
+ I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
I.TagType = TagTypeKind::Class;
I.IsTypeDef = true;
- BaseRecordInfo B(EmptySID, "F", "path/to/F", true, AccessSpecifier::AS_public,
- true);
- FunctionInfo FI;
- B.Children.Functions.push_back(FI);
- MemberTypeInfo BM(TypeInfo("int"), "X", AccessSpecifier::AS_private);
+ I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
+ AccessSpecifier::AS_public, true);
+ I.Bases.back().Children.Functions.emplace_back();
+ I.Bases.back().Members.emplace_back(TypeInfo("int"), "X",
+ AccessSpecifier::AS_private);
+ I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+ I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
// Documentation for the data member.
CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {},
@@ -112,47 +109,29 @@ TEST_F(BitcodeTest, emitRecordInfoBitcode) {
CommentInfo TopCommentChildren[] = {
CommentInfo(CommentKind::CK_ParagraphComment, BriefChildren)};
CommentInfo TopComment(CommentKind::CK_FullComment, TopCommentChildren);
- BM.Description.push_back(TopComment);
- MemberTypeInfo BMem[] = {std::move(BM)};
- B.Members = llvm::ArrayRef(BMem);
- BaseRecordInfo Bases[] = {std::move(B)};
- I.Bases = llvm::ArrayRef(Bases);
-
- MemberTypeInfo Mem[] = {std::move(M)};
- I.Members = llvm::ArrayRef(Mem);
- Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record)};
- I.Parents = llvm::ArrayRef(Parents);
- Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record)};
- I.VirtualParents = llvm::ArrayRef(VParents);
-
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record);
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo FI2;
- I.Children.Functions.push_back(FI2);
- EnumInfo EI;
- I.Children.Enums.push_back(EI);
+ I.Bases.back().Members.back().Description.emplace_back(std::move(TopComment));
+
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+ I.Children.Functions.emplace_back();
+ I.Children.Enums.emplace_back();
std::string WriteResult = writeInfo(&I, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckRecordInfo(&I, InfoAsRecord(ReadResults[0]));
+ CheckRecordInfo(&I, InfoAsRecord(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitFunctionInfoBitcode) {
FunctionInfo I;
I.Name = "f";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
I.ReturnType = TypeInfo("void");
- FieldTypeInfo P(TypeInfo("int"), "P");
- FieldTypeInfo Params[] = {std::move(P)};
- I.Params = llvm::ArrayRef(Params);
+ I.Params.emplace_back(TypeInfo("int"), "P");
I.Access = AccessSpecifier::AS_none;
@@ -160,23 +139,19 @@ TEST_F(BitcodeTest, emitFunctionInfoBitcode) {
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0]));
+ CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitMethodInfoBitcode) {
FunctionInfo I;
I.Name = "f";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
I.ReturnType = TypeInfo("void");
- FieldTypeInfo P(TypeInfo("int"), "P");
- FieldTypeInfo Params[] = {std::move(P)};
- I.Params = llvm::ArrayRef(Params);
+ I.Params.emplace_back(TypeInfo("int"), "P");
I.IsMethod = true;
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
@@ -186,36 +161,31 @@ TEST_F(BitcodeTest, emitMethodInfoBitcode) {
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0]));
+ CheckFunctionInfo(&I, InfoAsFunction(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitEnumInfoBitcode) {
EnumInfo I;
I.Name = "e";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- EnumValueInfo EV("X");
- EnumValueInfo Mems[] = {std::move(EV)};
- I.Members = llvm::ArrayRef(Mems);
+ I.Members.emplace_back("X");
I.Scoped = true;
std::string WriteResult = writeInfo(&I, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckEnumInfo(&I, InfoAsEnum(ReadResults[0]));
+ CheckEnumInfo(&I, InfoAsEnum(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitTypedefInfoBitcode) {
TypedefInfo I;
I.Name = "MyInt";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
I.Underlying = TypeInfo("unsigned");
@@ -226,13 +196,13 @@ TEST_F(BitcodeTest, emitTypedefInfoBitcode) {
CommentInfo(CommentKind::CK_ParagraphComment, BlankChildren)};
CommentInfo Top(CommentKind::CK_FullComment, TopChildren);
- I.Description.push_back(Top);
+ I.Description.emplace_back(std::move(Top));
std::string WriteResult = writeInfo(&I, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0]));
+ CheckTypedefInfo(&I, InfoAsTypedef(ReadResults[0].get()));
// Check one with no IsUsing set, no description, and no definition location.
TypedefInfo I2;
@@ -243,7 +213,7 @@ TEST_F(BitcodeTest, emitTypedefInfoBitcode) {
WriteResult = writeInfo(&I2, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckTypedefInfo(&I2, InfoAsTypedef(ReadResults[0]));
+ CheckTypedefInfo(&I2, InfoAsTypedef(ReadResults[0].get()));
}
TEST_F(BitcodeTest, emitInfoWithCommentBitcode) {
@@ -251,8 +221,7 @@ TEST_F(BitcodeTest, emitInfoWithCommentBitcode) {
F.Name = "F";
F.ReturnType = TypeInfo("void");
F.DefLoc = Location(0, 0, "test.cpp");
- FieldTypeInfo PI[] = {FieldTypeInfo(TypeInfo("int"), "I")};
- F.Params = llvm::ArrayRef(PI);
+ F.Params.emplace_back(TypeInfo("int"), "I");
// BlankLine
CommentInfo BlankChildren[] = {CommentInfo(CommentKind::CK_TextComment)};
@@ -324,13 +293,13 @@ TEST_F(BitcodeTest, emitInfoWithCommentBitcode) {
Verbatim, ParamOut, ParamIn, Return};
CommentInfo Top(CommentKind::CK_FullComment, TopChildren);
- F.Description.push_back(Top);
+ F.Description.emplace_back(std::move(Top));
std::string WriteResult = writeInfo(&F, this->Diags);
EXPECT_TRUE(WriteResult.size() > 0);
OwningPtrVec<Info> ReadResults = readInfo(WriteResult, 1, this->Diags);
- CheckFunctionInfo(&F, InfoAsFunction(ReadResults[0]));
+ CheckFunctionInfo(&F, InfoAsFunction(ReadResults[0].get()));
}
} // namespace doc
diff --git a/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp b/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
index 2e5466c172a18..92127da53b7bb 100644
--- a/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
@@ -54,10 +54,10 @@ TypedefInfo *InfoAsTypedef(Info *I) {
return static_cast<TypedefInfo *>(I);
}
-void CheckCommentInfo(ArrayRef<CommentInfo> Expected,
- ArrayRef<CommentInfo> Actual);
-void CheckCommentInfo(const OwningVec<CommentInfo> &Expected,
- const OwningVec<CommentInfo> &Actual);
+void CheckCommentInfo(const std::vector<CommentInfo> &Expected,
+ const std::vector<CommentInfo> &Actual);
+void CheckCommentInfo(const std::vector<OwnedPtr<CommentInfo>> &Expected,
+ const std::vector<OwnedPtr<CommentInfo>> &Actual);
void CheckCommentInfo(const CommentInfo &Expected, const CommentInfo &Actual) {
EXPECT_EQ(Expected.Kind, Actual.Kind);
@@ -84,71 +84,52 @@ void CheckCommentInfo(const CommentInfo &Expected, const CommentInfo &Actual) {
CheckCommentInfo(Expected.Children, Actual.Children);
}
-void CheckCommentInfo(ArrayRef<CommentInfo> Expected,
- ArrayRef<CommentInfo> Actual) {
- auto ItE = Expected.begin();
- auto ItA = Actual.begin();
- while (ItE != Expected.end() && ItA != Actual.end()) {
- CheckCommentInfo(*ItE, *ItA);
- ++ItE;
- ++ItA;
- }
- EXPECT_TRUE(ItE == Expected.end() && ItA == Actual.end());
+void CheckCommentInfo(const std::vector<CommentInfo> &Expected,
+ const std::vector<CommentInfo> &Actual) {
+ ASSERT_EQ(Expected.size(), Actual.size());
+ for (size_t Idx = 0; Idx < Actual.size(); ++Idx)
+ CheckCommentInfo(Expected[Idx], Actual[Idx]);
}
-void CheckCommentInfo(const OwningVec<CommentInfo> &Expected,
- const OwningVec<CommentInfo> &Actual) {
- auto ItE = Expected.begin();
- auto ItA = Actual.begin();
- while (ItE != Expected.end() && ItA != Actual.end()) {
- CheckCommentInfo(*ItE, *ItA);
- ++ItE;
- ++ItA;
- }
- EXPECT_TRUE(ItE == Expected.end() && ItA == Actual.end());
+void CheckCommentInfo(const std::vector<OwnedPtr<CommentInfo>> &Expected,
+ const std::vector<OwnedPtr<CommentInfo>> &Actual) {
+ ASSERT_EQ(Expected.size(), Actual.size());
+ for (size_t Idx = 0; Idx < Actual.size(); ++Idx)
+ CheckCommentInfo(*Expected[Idx], *Actual[Idx]);
}
-void CheckReference(const Reference &Expected, const Reference &Actual) {
+void CheckReference(Reference &Expected, Reference &Actual) {
EXPECT_EQ(Expected.Name, Actual.Name);
EXPECT_EQ(Expected.RefType, Actual.RefType);
EXPECT_EQ(Expected.Path, Actual.Path);
}
-void CheckTypeInfo(const TypeInfo *Expected, const TypeInfo *Actual) {
+void CheckTypeInfo(TypeInfo *Expected, TypeInfo *Actual) {
CheckReference(Expected->Type, Actual->Type);
}
-void CheckFieldTypeInfo(const FieldTypeInfo *Expected,
- const FieldTypeInfo *Actual) {
+void CheckFieldTypeInfo(FieldTypeInfo *Expected, FieldTypeInfo *Actual) {
CheckTypeInfo(Expected, Actual);
EXPECT_EQ(Expected->Name, Actual->Name);
}
-void CheckMemberTypeInfo(const MemberTypeInfo *Expected,
- const MemberTypeInfo *Actual) {
+void CheckMemberTypeInfo(MemberTypeInfo *Expected, MemberTypeInfo *Actual) {
CheckFieldTypeInfo(Expected, Actual);
EXPECT_EQ(Expected->Access, Actual->Access);
CheckCommentInfo(Expected->Description, Actual->Description);
}
-void CheckBaseInfo(const Info *Expected, const Info *Actual) {
+void CheckBaseInfo(Info *Expected, Info *Actual) {
EXPECT_EQ(size_t(20), Actual->USR.size());
EXPECT_EQ(Expected->Name, Actual->Name);
EXPECT_EQ(Expected->Path, Actual->Path);
- auto ItN_E = Expected->Namespace.begin();
- auto ItN_A = Actual->Namespace.begin();
- while (ItN_E != Expected->Namespace.end() &&
- ItN_A != Actual->Namespace.end()) {
- CheckReference(*ItN_E, *ItN_A);
- ++ItN_E;
- ++ItN_A;
- }
- EXPECT_TRUE(ItN_E == Expected->Namespace.end() &&
- ItN_A == Actual->Namespace.end());
+ 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]);
CheckCommentInfo(Expected->Description, Actual->Description);
}
-void CheckSymbolInfo(const SymbolInfo *Expected, const SymbolInfo *Actual) {
+void CheckSymbolInfo(SymbolInfo *Expected, SymbolInfo *Actual) {
CheckBaseInfo(Expected, Actual);
EXPECT_EQ(Expected->DefLoc.has_value(), Actual->DefLoc.has_value());
if (Expected->DefLoc && Actual->DefLoc.has_value()) {
@@ -157,186 +138,109 @@ void CheckSymbolInfo(const SymbolInfo *Expected, const SymbolInfo *Actual) {
EXPECT_EQ(Expected->DefLoc->EndLineNumber, Actual->DefLoc->EndLineNumber);
EXPECT_EQ(Expected->DefLoc->Filename, Actual->DefLoc->Filename);
}
- auto ItE = Expected->Loc.begin();
- auto ItA = Actual->Loc.begin();
- while (ItE != Expected->Loc.end() && ItA != Actual->Loc.end()) {
- EXPECT_EQ(*ItE, *ItA);
- ++ItE;
- ++ItA;
- }
- EXPECT_TRUE(ItE == Expected->Loc.end() && ItA == Actual->Loc.end());
+ 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(const FunctionInfo *Expected,
- const FunctionInfo *Actual) {
+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);
- for (size_t Idx = 0; Idx < Expected->Params.size(); ++Idx) {
+ 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(const EnumInfo *Expected, const EnumInfo *Actual) {
+void CheckEnumInfo(EnumInfo *Expected, EnumInfo *Actual) {
CheckSymbolInfo(Expected, Actual);
EXPECT_EQ(Expected->Scoped, Actual->Scoped);
- auto ItM_E = Expected->Members.begin();
- auto ItM_A = Actual->Members.begin();
- while (ItM_E != Expected->Members.end() && ItM_A != Actual->Members.end()) {
- EXPECT_EQ(*ItM_E, *ItM_A);
- ++ItM_E;
- ++ItM_A;
- }
- EXPECT_TRUE(ItM_E == Expected->Members.end() &&
- ItM_A == Actual->Members.end());
+ 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 CheckTypedefInfo(const TypedefInfo *Expected, const TypedefInfo *Actual) {
+void CheckTypedefInfo(TypedefInfo *Expected, TypedefInfo *Actual) {
CheckSymbolInfo(Expected, Actual);
EXPECT_EQ(Expected->IsUsing, Actual->IsUsing);
CheckTypeInfo(&Expected->Underlying, &Actual->Underlying);
}
-void CheckNamespaceInfo(const NamespaceInfo *Expected,
- const NamespaceInfo *Actual) {
+void CheckNamespaceInfo(NamespaceInfo *Expected, NamespaceInfo *Actual) {
CheckBaseInfo(Expected, Actual);
ASSERT_EQ(Expected->Children.Namespaces.size(),
Actual->Children.Namespaces.size());
- auto ItN_E = Expected->Children.Namespaces.begin();
- auto ItN_A = Actual->Children.Namespaces.begin();
- while (ItN_E != Expected->Children.Namespaces.end() &&
- ItN_A != Actual->Children.Namespaces.end()) {
- CheckReference(*ItN_E, *ItN_A);
- ++ItN_E;
- ++ItN_A;
- }
- EXPECT_TRUE(ItN_E == Expected->Children.Namespaces.end() &&
- ItN_A == Actual->Children.Namespaces.end());
-
- auto ItR_E = Expected->Children.Records.begin();
- auto ItR_A = Actual->Children.Records.begin();
- while (ItR_E != Expected->Children.Records.end() &&
- ItR_A != Actual->Children.Records.end()) {
- CheckReference(*ItR_E, *ItR_A);
- ++ItR_E;
- ++ItR_A;
+ auto ItExpected = Expected->Children.Namespaces.begin();
+ auto ItActual = Actual->Children.Namespaces.begin();
+ while (ItExpected != Expected->Children.Namespaces.end()) {
+ CheckReference(*ItExpected, *ItActual);
+ ++ItExpected;
+ ++ItActual;
}
- EXPECT_TRUE(ItR_E == Expected->Children.Records.end() &&
- ItR_A == Actual->Children.Records.end());
-
- auto ItF_E = Expected->Children.Functions.begin();
- auto ItF_A = Actual->Children.Functions.begin();
- while (ItF_E != Expected->Children.Functions.end() &&
- ItF_A != Actual->Children.Functions.end()) {
- CheckFunctionInfo(&(*ItF_E), &(*ItF_A));
- ++ItF_E;
- ++ItF_A;
- }
- EXPECT_TRUE(ItF_E == Expected->Children.Functions.end() &&
- ItF_A == Actual->Children.Functions.end());
-
- auto ItEnum_E = Expected->Children.Enums.begin();
- auto ItEnum_A = Actual->Children.Enums.begin();
- while (ItEnum_E != Expected->Children.Enums.end() &&
- ItEnum_A != Actual->Children.Enums.end()) {
- CheckEnumInfo(&(*ItEnum_E), &(*ItEnum_A));
- ++ItEnum_E;
- ++ItEnum_A;
- }
- EXPECT_TRUE(ItEnum_E == Expected->Children.Enums.end() &&
- ItEnum_A == Actual->Children.Enums.end());
+
+ ASSERT_EQ(Expected->Children.Records.size(), Actual->Children.Records.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Records.size(); ++Idx)
+ CheckReference(Expected->Children.Records[Idx],
+ Actual->Children.Records[Idx]);
+
+ ASSERT_EQ(Expected->Children.Functions.size(),
+ Actual->Children.Functions.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Functions.size(); ++Idx)
+ CheckFunctionInfo(&Expected->Children.Functions[Idx],
+ &Actual->Children.Functions[Idx]);
+
+ ASSERT_EQ(Expected->Children.Enums.size(), Actual->Children.Enums.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Enums.size(); ++Idx)
+ CheckEnumInfo(&Expected->Children.Enums[Idx], &Actual->Children.Enums[Idx]);
}
-void CheckRecordInfo(const RecordInfo *Expected, const RecordInfo *Actual) {
+void CheckRecordInfo(RecordInfo *Expected, RecordInfo *Actual) {
CheckSymbolInfo(Expected, Actual);
EXPECT_EQ(Expected->TagType, Actual->TagType);
EXPECT_EQ(Expected->IsTypeDef, Actual->IsTypeDef);
- auto ItM_E = Expected->Members.begin();
- auto ItM_A = Actual->Members.begin();
- while (ItM_E != Expected->Members.end() && ItM_A != Actual->Members.end()) {
- EXPECT_EQ(*ItM_E, *ItM_A);
- ++ItM_E;
- ++ItM_A;
- }
- EXPECT_TRUE(ItM_E == Expected->Members.end() &&
- ItM_A == Actual->Members.end());
-
- auto ItP_E = Expected->Parents.begin();
- auto ItP_A = Actual->Parents.begin();
- while (ItP_E != Expected->Parents.end() && ItP_A != Actual->Parents.end()) {
- CheckReference(*ItP_E, *ItP_A);
- ++ItP_E;
- ++ItP_A;
- }
- EXPECT_TRUE(ItP_E == Expected->Parents.end() &&
- ItP_A == Actual->Parents.end());
-
- auto ItVP_E = Expected->VirtualParents.begin();
- auto ItVP_A = Actual->VirtualParents.begin();
- while (ItVP_E != Expected->VirtualParents.end() &&
- ItVP_A != Actual->VirtualParents.end()) {
- CheckReference(*ItVP_E, *ItVP_A);
- ++ItVP_E;
- ++ItVP_A;
- }
- EXPECT_TRUE(ItVP_E == Expected->VirtualParents.end() &&
- ItVP_A == Actual->VirtualParents.end());
-
- auto ItB_E = Expected->Bases.begin();
- auto ItB_A = Actual->Bases.begin();
- while (ItB_E != Expected->Bases.end() && ItB_A != Actual->Bases.end()) {
- CheckBaseRecordInfo(&(*ItB_E), &(*ItB_A));
- ++ItB_E;
- ++ItB_A;
- }
- EXPECT_TRUE(ItB_E == Expected->Bases.end() && ItB_A == Actual->Bases.end());
-
- auto ItR_E = Expected->Children.Records.begin();
- auto ItR_A = Actual->Children.Records.begin();
- while (ItR_E != Expected->Children.Records.end() &&
- ItR_A != Actual->Children.Records.end()) {
- CheckReference(*ItR_E, *ItR_A);
- ++ItR_E;
- ++ItR_A;
- }
- EXPECT_TRUE(ItR_E == Expected->Children.Records.end() &&
- ItR_A == Actual->Children.Records.end());
-
- auto ItF_E = Expected->Children.Functions.begin();
- auto ItF_A = Actual->Children.Functions.begin();
- while (ItF_E != Expected->Children.Functions.end() &&
- ItF_A != Actual->Children.Functions.end()) {
- CheckFunctionInfo(&(*ItF_E), &(*ItF_A));
- ++ItF_E;
- ++ItF_A;
- }
- EXPECT_TRUE(ItF_E == Expected->Children.Functions.end() &&
- ItF_A == Actual->Children.Functions.end());
-
- auto ItEnum_E = Expected->Children.Enums.begin();
- auto ItEnum_A = Actual->Children.Enums.begin();
- while (ItEnum_E != Expected->Children.Enums.end() &&
- ItEnum_A != Actual->Children.Enums.end()) {
- CheckEnumInfo(&(*ItEnum_E), &(*ItEnum_A));
- ++ItEnum_E;
- ++ItEnum_A;
- }
- EXPECT_TRUE(ItEnum_E == Expected->Children.Enums.end() &&
- ItEnum_A == Actual->Children.Enums.end());
+ 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->Bases.size(), Actual->Bases.size());
+ for (size_t Idx = 0; Idx < Actual->Bases.size(); ++Idx)
+ CheckBaseRecordInfo(&Expected->Bases[Idx], &Actual->Bases[Idx]);
+
+ ASSERT_EQ(Expected->Children.Records.size(), Actual->Children.Records.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Records.size(); ++Idx)
+ CheckReference(Expected->Children.Records[Idx],
+ Actual->Children.Records[Idx]);
+
+ ASSERT_EQ(Expected->Children.Functions.size(),
+ Actual->Children.Functions.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Functions.size(); ++Idx)
+ CheckFunctionInfo(&Expected->Children.Functions[Idx],
+ &Actual->Children.Functions[Idx]);
+
+ ASSERT_EQ(Expected->Children.Enums.size(), Actual->Children.Enums.size());
+ for (size_t Idx = 0; Idx < Actual->Children.Enums.size(); ++Idx)
+ CheckEnumInfo(&Expected->Children.Enums[Idx], &Actual->Children.Enums[Idx]);
}
-void CheckBaseRecordInfo(const BaseRecordInfo *Expected,
- const BaseRecordInfo *Actual) {
+void CheckBaseRecordInfo(BaseRecordInfo *Expected, BaseRecordInfo *Actual) {
CheckRecordInfo(Expected, Actual);
EXPECT_EQ(Expected->IsVirtual, Actual->IsVirtual);
@@ -344,7 +248,7 @@ void CheckBaseRecordInfo(const BaseRecordInfo *Expected,
EXPECT_EQ(Expected->IsParent, Actual->IsParent);
}
-void CheckIndex(const Index &Expected, const Index &Actual) {
+void CheckIndex(Index &Expected, Index &Actual) {
CheckReference(Expected, Actual);
ASSERT_EQ(Expected.Children.size(), Actual.Children.size());
for (auto &[_, C] : Expected.Children)
diff --git a/clang-tools-extra/unittests/clang-doc/ClangDocTest.h b/clang-tools-extra/unittests/clang-doc/ClangDocTest.h
index 1525b1ed382ce..9b1a26af0cdf6 100644
--- a/clang-tools-extra/unittests/clang-doc/ClangDocTest.h
+++ b/clang-tools-extra/unittests/clang-doc/ClangDocTest.h
@@ -31,32 +31,25 @@ FunctionInfo *InfoAsFunction(Info *I);
EnumInfo *InfoAsEnum(Info *I);
TypedefInfo *InfoAsTypedef(Info *I);
-void CheckCommentInfo(ArrayRef<CommentInfo> Expected,
- ArrayRef<CommentInfo> Actual);
-void CheckCommentInfo(const OwningVec<CommentInfo> &Expected,
- const OwningVec<CommentInfo> &Actual);
-void CheckReference(const Reference &Expected, const Reference &Actual);
-void CheckTypeInfo(const TypeInfo *Expected, const TypeInfo *Actual);
-void CheckFieldTypeInfo(const FieldTypeInfo *Expected,
- const FieldTypeInfo *Actual);
-void CheckMemberTypeInfo(const MemberTypeInfo *Expected,
- const MemberTypeInfo *Actual);
+// 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(const Info *Expected, const Info *Actual);
-void CheckSymbolInfo(const SymbolInfo *Expected, const SymbolInfo *Actual);
-void CheckFunctionInfo(const FunctionInfo *Expected,
- const FunctionInfo *Actual);
-void CheckEnumInfo(const EnumInfo *Expected, const EnumInfo *Actual);
-void CheckTypedefInfo(const TypedefInfo *Expected, const TypedefInfo *Actual);
-void CheckNamespaceInfo(const NamespaceInfo *Expected,
- const NamespaceInfo *Actual);
-void CheckRecordInfo(const RecordInfo *Expected, const RecordInfo *Actual);
-void CheckBaseRecordInfo(const BaseRecordInfo *Expected,
- const BaseRecordInfo *Actual);
+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 CheckTypedefInfo(TypedefInfo *Expected, TypedefInfo *Actual);
+void CheckNamespaceInfo(NamespaceInfo *Expected, NamespaceInfo *Actual);
+void CheckRecordInfo(RecordInfo *Expected, RecordInfo *Actual);
+void CheckBaseRecordInfo(BaseRecordInfo *Expected, BaseRecordInfo *Actual);
-void CheckIndex(const Index &Expected, const Index &Actual);
+void CheckIndex(Index &Expected, Index &Actual);
class ClangDocContextTest : public ::testing::Test {
protected:
diff --git a/clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp
index e352abbe0801f..38f37bd535239 100644
--- a/clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp
@@ -28,8 +28,7 @@ TEST_F(GeneratorTest, emitIndex) {
InfoC->USR = serialize::hashUSR("3");
Reference RefB = Reference(SymbolID(), "B");
RefB.USR = serialize::hashUSR("2");
- Reference NsC[] = {std::move(RefB)};
- InfoC->Namespace = llvm::ArrayRef(NsC);
+ InfoC->Namespace = {std::move(RefB)};
Generator::addInfoToIndex(Idx, InfoC.get());
auto InfoD = std::make_unique<Info>();
InfoD->Name = "D";
@@ -41,8 +40,7 @@ TEST_F(GeneratorTest, emitIndex) {
RefD.USR = serialize::hashUSR("4");
Reference RefE = Reference(SymbolID(), "E");
RefE.USR = serialize::hashUSR("5");
- Reference NsF[] = {std::move(RefE), std::move(RefD)};
- InfoF->Namespace = llvm::ArrayRef(NsF);
+ InfoF->Namespace = {std::move(RefE), std::move(RefD)};
Generator::addInfoToIndex(Idx, InfoF.get());
auto InfoG = std::make_unique<Info>(InfoType::IT_namespace);
Generator::addInfoToIndex(Idx, InfoG.get());
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index 509699f20aa09..6edd303dbc326 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -19,54 +19,39 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
RecordInfo I;
I.Name = "Foo";
I.IsTypeDef = false;
- Reference Ns[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "GlobalNamespace", InfoType::IT_namespace);
I.Path = "GlobalNamespace";
I.DefLoc = Location(1, 1, "main.cpp");
I.TagType = TagTypeKind::Class;
I.Template = TemplateInfo();
- TemplateParamInfo TParams[] = {TemplateParamInfo("class T")};
- I.Template->Params = llvm::ArrayRef(TParams);
+ I.Template->Params.emplace_back("class T");
- EnumInfo E;
- E.Name = "Color";
- E.Scoped = false;
- EnumValueInfo EV[] = {EnumValueInfo("RED", "0")};
- E.Members = llvm::ArrayRef(EV);
- I.Children.Enums.push_back(E);
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "Color";
+ I.Children.Enums.back().Scoped = false;
+ I.Children.Enums.back().Members.emplace_back();
+ I.Children.Enums.back().Members.back().Name = "RED";
+ I.Children.Enums.back().Members.back().Value = "0";
- MemberTypeInfo M[] = {
- MemberTypeInfo(TypeInfo("int"), "X", AccessSpecifier::AS_protected)};
- I.Members = llvm::ArrayRef(M);
+ I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_protected);
- BaseRecordInfo B(EmptySID, "F", "path/to/F", true, AccessSpecifier::AS_public,
- true);
- FunctionInfo F;
- F.Name = "InheritedFunctionOne";
- B.Children.Functions.push_back(F);
- MemberTypeInfo BM[] = {
- MemberTypeInfo(TypeInfo("int"), "N", AccessSpecifier::AS_public)};
- B.Members = llvm::ArrayRef(BM);
-
- BaseRecordInfo Bases[] = {std::move(B)};
- I.Bases = llvm::ArrayRef(Bases);
+ I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
+ AccessSpecifier::AS_public, true);
+ I.Bases.back().Children.Functions.emplace_back();
+ I.Bases.back().Children.Functions.back().Name = "InheritedFunctionOne";
+ I.Bases.back().Members.emplace_back(TypeInfo("int"), "N",
+ AccessSpecifier::AS_public);
// F is in the global namespace
- Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record, "")};
- I.Parents = llvm::ArrayRef(Parents);
- Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record,
- "path::to::G::G", "path/to/G")};
- I.VirtualParents = llvm::ArrayRef(VParents);
-
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
- "path::to::A::r::ChildStruct", "path/to/A/r");
- I.Children.Records.push_back(ChildStruct);
+ I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "");
+ I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record,
+ "path::to::G::G", "path/to/G");
- FunctionInfo F2;
- F2.Name = "OneFunction";
- I.Children.Functions.push_back(F2);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
+ "path::to::A::r::ChildStruct", "path/to/A/r");
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
auto G = getJSONGenerator();
assert(G);
@@ -212,26 +197,20 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) {
NamespaceInfo I;
I.Name = "Namespace";
I.Path = "path/to/A";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace,
"path::to::A::Namespace::ChildNamespace",
"path/to/A/Namespace");
I.Children.Namespaces.push_back(NewNamespace);
-
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
- "path::to::A::Namespace::ChildStruct",
- "path/to/A/Namespace");
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo F;
- F.Name = "OneFunction";
- F.Access = AccessSpecifier::AS_none;
- I.Children.Functions.push_back(F);
-
- EnumInfo E;
- E.Name = "OneEnum";
- I.Children.Enums.push_back(E);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
+ "path::to::A::Namespace::ChildStruct",
+ "path/to/A/Namespace");
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
+ I.Children.Functions.back().Access = AccessSpecifier::AS_none;
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "OneEnum";
auto G = getJSONGenerator();
assert(G);
diff --git a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
index 2dc472a352fd8..6661360049881 100644
--- a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
@@ -26,22 +26,16 @@ class MDGeneratorTest : public ClangDocContextTest {};
TEST_F(MDGeneratorTest, emitNamespaceMD) {
NamespaceInfo I;
I.Name = "Namespace";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace);
I.Children.Namespaces.push_back(NewNamespace);
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record);
- I.Children.Records.push_back(ChildStruct);
-
- FunctionInfo F;
- F.Name = "OneFunction";
- F.Access = AccessSpecifier::AS_none;
- I.Children.Functions.push_back(F);
-
- EnumInfo E;
- E.Name = "OneEnum";
- I.Children.Enums.push_back(E);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
+ I.Children.Functions.back().Access = AccessSpecifier::AS_none;
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "OneEnum";
auto G = getMDGenerator();
assert(G);
@@ -85,31 +79,21 @@ TEST_F(MDGeneratorTest, emitNamespaceMD) {
TEST_F(MDGeneratorTest, emitRecordMD) {
RecordInfo I;
I.Name = "r";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- MemberTypeInfo M[] = {
- MemberTypeInfo(TypeInfo("int"), "X", AccessSpecifier::AS_private)};
- I.Members = llvm::ArrayRef(M);
+ I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
I.TagType = TagTypeKind::Class;
- Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record)};
- I.Parents = llvm::ArrayRef(Parents);
- Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record)};
- I.VirtualParents = llvm::ArrayRef(VParents);
-
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record);
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo F;
- F.Name = "OneFunction";
- I.Children.Functions.push_back(F);
+ I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+ I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
- EnumInfo E;
- E.Name = "OneEnum";
- I.Children.Enums.push_back(E);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "OneEnum";
auto G = getMDGenerator();
assert(G);
@@ -159,18 +143,15 @@ ChildStruct
TEST_F(MDGeneratorTest, emitFunctionMD) {
FunctionInfo I;
I.Name = "f";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
I.Access = AccessSpecifier::AS_none;
I.ReturnType = TypeInfo("void");
- FieldTypeInfo P[] = {FieldTypeInfo(TypeInfo("int"), "P")};
- I.Params = llvm::ArrayRef(P);
+ I.Params.emplace_back(TypeInfo("int"), "P");
I.IsMethod = true;
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
@@ -194,15 +175,12 @@ TEST_F(MDGeneratorTest, emitFunctionMD) {
TEST_F(MDGeneratorTest, emitEnumMD) {
EnumInfo I;
I.Name = "e";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- EnumValueInfo EV[] = {EnumValueInfo("X")};
- I.Members = llvm::ArrayRef(EV);
+ I.Members.emplace_back("X");
I.Scoped = true;
auto G = getMDGenerator();
@@ -230,9 +208,8 @@ TEST_F(MDGeneratorTest, emitCommentMD) {
I.DefLoc = Location(10, 10, "test.cpp");
I.ReturnType = TypeInfo("void");
- FieldTypeInfo PI[] = {FieldTypeInfo(TypeInfo("int"), "I"),
- FieldTypeInfo(TypeInfo("int"), "J")};
- I.Params = llvm::ArrayRef(PI);
+ I.Params.emplace_back(TypeInfo("int"), "I");
+ I.Params.emplace_back(TypeInfo("int"), "J");
I.Access = AccessSpecifier::AS_none;
CommentInfo Top;
diff --git a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
index 50374743681e3..15b791a044d2d 100644
--- a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
@@ -18,200 +18,150 @@ class MergeTest : public ClangDocContextTest {};
TEST_F(MergeTest, mergeNamespaceInfos) {
NamespaceInfo One;
One.Name = "Namespace";
- Reference Ns1[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- One.Namespace = llvm::ArrayRef(Ns1);
+ One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference RA(NonEmptySID, "ChildNamespace", InfoType::IT_namespace);
One.Children.Namespaces.push_back(RA);
- Reference RC1(NonEmptySID, "ChildStruct", InfoType::IT_record);
- One.Children.Records.push_back(RC1);
-
- FunctionInfo F1;
- F1.Name = "OneFunction";
- F1.USR = NonEmptySID;
- One.Children.Functions.push_back(F1);
-
- EnumInfo E1;
- E1.Name = "OneEnum";
- E1.USR = NonEmptySID;
- One.Children.Enums.push_back(E1);
+ One.Children.Records.emplace_back(NonEmptySID, "ChildStruct",
+ InfoType::IT_record);
+ One.Children.Functions.emplace_back();
+ One.Children.Functions.back().Name = "OneFunction";
+ One.Children.Functions.back().USR = NonEmptySID;
+ One.Children.Enums.emplace_back();
+ One.Children.Enums.back().Name = "OneEnum";
+ One.Children.Enums.back().USR = NonEmptySID;
NamespaceInfo Two;
Two.Name = "Namespace";
- Reference Ns2[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Two.Namespace = llvm::ArrayRef(Ns2);
+ Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference RB(EmptySID, "OtherChildNamespace", InfoType::IT_namespace);
Two.Children.Namespaces.push_back(RB);
- Reference RC2(EmptySID, "OtherChildStruct", InfoType::IT_record);
- Two.Children.Records.push_back(RC2);
-
- FunctionInfo F2;
- F2.Name = "TwoFunction";
- Two.Children.Functions.push_back(F2);
-
- EnumInfo E2;
- E2.Name = "TwoEnum";
- Two.Children.Enums.push_back(E2);
+ Two.Children.Records.emplace_back(EmptySID, "OtherChildStruct",
+ InfoType::IT_record);
+ Two.Children.Functions.emplace_back();
+ Two.Children.Functions.back().Name = "TwoFunction";
+ Two.Children.Enums.emplace_back();
+ Two.Children.Enums.back().Name = "TwoEnum";
OwningPtrVec<Info> Infos;
- Infos.push_back(&One);
- Infos.push_back(&Two);
+ Infos.emplace_back(allocatePtr<NamespaceInfo>(std::move(One)));
+ Infos.emplace_back(allocatePtr<NamespaceInfo>(std::move(Two)));
- NamespaceInfo Expected;
- Expected.Name = "Namespace";
- Reference NsExpected[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Expected.Namespace = llvm::ArrayRef(NsExpected);
+ auto Expected = allocatePtr<NamespaceInfo>();
+ Expected->Name = "Namespace";
+ Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference RC(NonEmptySID, "ChildNamespace", InfoType::IT_namespace);
- Expected.Children.Namespaces.push_back(RC);
- Reference RCE1(NonEmptySID, "ChildStruct", InfoType::IT_record);
- Expected.Children.Records.push_back(RCE1);
+ Expected->Children.Namespaces.push_back(RC);
+ Expected->Children.Records.emplace_back(NonEmptySID, "ChildStruct",
+ InfoType::IT_record);
Reference RD(EmptySID, "OtherChildNamespace", InfoType::IT_namespace);
- Expected.Children.Namespaces.push_back(RD);
- Reference RCE2(EmptySID, "OtherChildStruct", InfoType::IT_record);
- Expected.Children.Records.push_back(RCE2);
-
- FunctionInfo FE1;
- FE1.Name = "OneFunction";
- FE1.USR = NonEmptySID;
- Expected.Children.Functions.push_back(FE1);
-
- FunctionInfo FE2;
- FE2.Name = "TwoFunction";
- Expected.Children.Functions.push_back(FE2);
-
- EnumInfo EE1;
- EE1.Name = "OneEnum";
- EE1.USR = NonEmptySID;
- Expected.Children.Enums.push_back(EE1);
-
- EnumInfo EE2;
- EE2.Name = "TwoEnum";
- Expected.Children.Enums.push_back(EE2);
+ Expected->Children.Namespaces.push_back(RD);
+ Expected->Children.Records.emplace_back(EmptySID, "OtherChildStruct",
+ InfoType::IT_record);
+ Expected->Children.Functions.emplace_back();
+ Expected->Children.Functions.back().Name = "OneFunction";
+ Expected->Children.Functions.back().USR = NonEmptySID;
+ Expected->Children.Functions.emplace_back();
+ Expected->Children.Functions.back().Name = "TwoFunction";
+ Expected->Children.Enums.emplace_back();
+ Expected->Children.Enums.back().Name = "OneEnum";
+ Expected->Children.Enums.back().USR = NonEmptySID;
+ Expected->Children.Enums.emplace_back();
+ Expected->Children.Enums.back().Name = "TwoEnum";
auto Actual = mergeInfos(Infos);
assert(Actual);
- CheckNamespaceInfo(InfoAsNamespace(&Expected), InfoAsNamespace(Actual.get()));
+ CheckNamespaceInfo(InfoAsNamespace(Expected.get()),
+ InfoAsNamespace(Actual.get().get()));
}
TEST_F(MergeTest, mergeRecordInfos) {
RecordInfo One;
One.Name = "r";
One.IsTypeDef = true;
- Reference Ns1[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- One.Namespace = llvm::ArrayRef(Ns1);
+ One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
One.DefLoc = Location(10, 10, "test.cpp");
- MemberTypeInfo M1[] = {
- MemberTypeInfo(TypeInfo("int"), "X", AccessSpecifier::AS_private)};
- One.Members = llvm::ArrayRef(M1);
+ One.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
One.TagType = TagTypeKind::Class;
- Reference P1[] = {Reference(EmptySID, "F", InfoType::IT_record)};
- One.Parents = llvm::ArrayRef(P1);
- Reference VP1[] = {Reference(EmptySID, "G", InfoType::IT_record)};
- One.VirtualParents = llvm::ArrayRef(VP1);
-
- BaseRecordInfo B1[] = {BaseRecordInfo(EmptySID, "F", "path/to/F", true,
- AccessSpecifier::AS_protected, true)};
- One.Bases = llvm::ArrayRef(B1);
- Reference RCShared1(NonEmptySID, "SharedChildStruct", InfoType::IT_record);
- One.Children.Records.push_back(RCShared1);
-
- FunctionInfo F1;
- F1.Name = "OneFunction";
- F1.USR = NonEmptySID;
- One.Children.Functions.push_back(F1);
-
- EnumInfo E1;
- E1.Name = "OneEnum";
- E1.USR = NonEmptySID;
- One.Children.Enums.push_back(E1);
+ One.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+ One.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+ One.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
+ AccessSpecifier::AS_protected, true);
+ One.Children.Records.emplace_back(NonEmptySID, "SharedChildStruct",
+ InfoType::IT_record);
+ One.Children.Functions.emplace_back();
+ One.Children.Functions.back().Name = "OneFunction";
+ One.Children.Functions.back().USR = NonEmptySID;
+ One.Children.Enums.emplace_back();
+ One.Children.Enums.back().Name = "OneEnum";
+ One.Children.Enums.back().USR = NonEmptySID;
RecordInfo Two;
Two.Name = "r";
- Reference Ns2[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Two.Namespace = llvm::ArrayRef(Ns2);
+ Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Location Loc2(12, 12, "test.cpp");
- Two.Loc.push_back(Loc2);
+ Two.Loc.emplace_back(12, 12, "test.cpp");
Two.TagType = TagTypeKind::Class;
- Reference RCShared2(NonEmptySID, "SharedChildStruct", InfoType::IT_record,
- "path");
- Two.Children.Records.push_back(RCShared2);
-
- FunctionInfo F2;
- F2.Name = "TwoFunction";
- Two.Children.Functions.push_back(F2);
-
- EnumInfo E2;
- E2.Name = "TwoEnum";
- Two.Children.Enums.push_back(E2);
+ Two.Children.Records.emplace_back(NonEmptySID, "SharedChildStruct",
+ InfoType::IT_record, "path");
+ Two.Children.Functions.emplace_back();
+ Two.Children.Functions.back().Name = "TwoFunction";
+ Two.Children.Enums.emplace_back();
+ Two.Children.Enums.back().Name = "TwoEnum";
OwningPtrVec<Info> Infos;
- Infos.push_back(&One);
- Infos.push_back(&Two);
-
- RecordInfo Expected;
- Expected.Name = "r";
- Expected.IsTypeDef = true;
- Reference NsE[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Expected.Namespace = llvm::ArrayRef(NsE);
-
- Expected.DefLoc = Location(10, 10, "test.cpp");
- Location LocE(12, 12, "test.cpp");
- Expected.Loc.push_back(LocE);
-
- MemberTypeInfo ME[] = {
- MemberTypeInfo(TypeInfo("int"), "X", AccessSpecifier::AS_private)};
- Expected.Members = llvm::ArrayRef(ME);
- Expected.TagType = TagTypeKind::Class;
- Reference PE[] = {Reference(EmptySID, "F", InfoType::IT_record)};
- Expected.Parents = llvm::ArrayRef(PE);
- Reference VPE[] = {Reference(EmptySID, "G", InfoType::IT_record)};
- Expected.VirtualParents = llvm::ArrayRef(VPE);
- BaseRecordInfo BE[] = {BaseRecordInfo(EmptySID, "F", "path/to/F", true,
- AccessSpecifier::AS_protected, true)};
- Expected.Bases = llvm::ArrayRef(BE);
-
- Reference RCSharedE(NonEmptySID, "SharedChildStruct", InfoType::IT_record,
- "path");
- Expected.Children.Records.push_back(RCSharedE);
- FunctionInfo FE1;
- FE1.Name = "OneFunction";
- FE1.USR = NonEmptySID;
- Expected.Children.Functions.push_back(FE1);
-
- FunctionInfo FE2;
- FE2.Name = "TwoFunction";
- Expected.Children.Functions.push_back(FE2);
-
- EnumInfo EE1;
- EE1.Name = "OneEnum";
- EE1.USR = NonEmptySID;
- Expected.Children.Enums.push_back(EE1);
-
- EnumInfo EE2;
- EE2.Name = "TwoEnum";
- Expected.Children.Enums.push_back(EE2);
+ Infos.emplace_back(allocatePtr<RecordInfo>(std::move(One)));
+ Infos.emplace_back(allocatePtr<RecordInfo>(std::move(Two)));
+
+ auto Expected = allocatePtr<RecordInfo>();
+ Expected->Name = "r";
+ Expected->IsTypeDef = true;
+ Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+ Expected->DefLoc = Location(10, 10, "test.cpp");
+ Expected->Loc.emplace_back(12, 12, "test.cpp");
+
+ Expected->Members.emplace_back(TypeInfo("int"), "X",
+ AccessSpecifier::AS_private);
+ Expected->TagType = TagTypeKind::Class;
+ Expected->Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+ Expected->VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+ Expected->Bases.emplace_back(EmptySID, "F", "path/to/F", true,
+ AccessSpecifier::AS_protected, true);
+
+ Expected->Children.Records.emplace_back(NonEmptySID, "SharedChildStruct",
+ InfoType::IT_record, "path");
+ Expected->Children.Functions.emplace_back();
+ Expected->Children.Functions.back().Name = "OneFunction";
+ Expected->Children.Functions.back().USR = NonEmptySID;
+ Expected->Children.Functions.emplace_back();
+ Expected->Children.Functions.back().Name = "TwoFunction";
+ Expected->Children.Enums.emplace_back();
+ Expected->Children.Enums.back().Name = "OneEnum";
+ Expected->Children.Enums.back().USR = NonEmptySID;
+ Expected->Children.Enums.emplace_back();
+ Expected->Children.Enums.back().Name = "TwoEnum";
auto Actual = mergeInfos(Infos);
assert(Actual);
- CheckRecordInfo(InfoAsRecord(&Expected), InfoAsRecord(Actual.get()));
+ CheckRecordInfo(InfoAsRecord(Expected.get()),
+ InfoAsRecord(Actual.get().get()));
}
TEST_F(MergeTest, mergeFunctionInfos) {
FunctionInfo One;
One.Name = "f";
- Reference Ns1[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- One.Namespace = llvm::ArrayRef(Ns1);
+ One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
One.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- One.Loc.push_back(Loc1);
+ One.Loc.emplace_back(12, 12, "test.cpp");
One.IsMethod = true;
One.Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
@@ -220,106 +170,89 @@ TEST_F(MergeTest, mergeFunctionInfos) {
CommentInfo(CommentKind::CK_TextComment, {}, "This is a text comment.")};
CommentInfo OnePara[] = {
CommentInfo(CommentKind::CK_ParagraphComment, OneText)};
- CommentInfo TopOne(CommentKind::CK_FullComment, OnePara);
- One.Description.push_back(TopOne);
+ One.Description.emplace_back(CommentKind::CK_FullComment, OnePara);
FunctionInfo Two;
Two.Name = "f";
- Reference Ns2[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Two.Namespace = llvm::ArrayRef(Ns2);
+ Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Location Loc2(12, 12, "test.cpp");
- Two.Loc.push_back(Loc2);
+ Two.Loc.emplace_back(12, 12, "test.cpp");
Two.ReturnType = TypeInfo("void");
- FieldTypeInfo P2(TypeInfo("int"), "P");
- FieldTypeInfo Params2[] = {std::move(P2)};
- Two.Params = llvm::ArrayRef(Params2);
+ Two.Params.emplace_back(TypeInfo("int"), "P");
CommentInfo TwoText[] = {
CommentInfo(CommentKind::CK_TextComment, {}, "This is a text comment.")};
CommentInfo TwoPara[] = {
CommentInfo(CommentKind::CK_ParagraphComment, TwoText)};
- CommentInfo TopTwo(CommentKind::CK_FullComment, TwoPara);
- Two.Description.push_back(TopTwo);
+ Two.Description.emplace_back(CommentKind::CK_FullComment, TwoPara);
OwningPtrVec<Info> Infos;
- Infos.push_back(&One);
- Infos.push_back(&Two);
+ Infos.emplace_back(allocatePtr<FunctionInfo>(std::move(One)));
+ Infos.emplace_back(allocatePtr<FunctionInfo>(std::move(Two)));
- FunctionInfo Expected;
- Expected.Name = "f";
- Reference NsE[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Expected.Namespace = llvm::ArrayRef(NsE);
+ auto Expected = allocatePtr<FunctionInfo>();
+ Expected->Name = "f";
+ Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Expected.DefLoc = Location(10, 10, "test.cpp");
- Location LocE(12, 12, "test.cpp");
- Expected.Loc.push_back(LocE);
+ Expected->DefLoc = Location(10, 10, "test.cpp");
+ Expected->Loc.emplace_back(12, 12, "test.cpp");
- Expected.ReturnType = TypeInfo("void");
- FieldTypeInfo PE(TypeInfo("int"), "P");
- FieldTypeInfo ParamsE[] = {std::move(PE)};
- Expected.Params = llvm::ArrayRef(ParamsE);
- Expected.IsMethod = true;
- Expected.Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
+ Expected->ReturnType = TypeInfo("void");
+ Expected->Params.emplace_back(TypeInfo("int"), "P");
+ Expected->IsMethod = true;
+ Expected->Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
CommentInfo ExpectedText[] = {
CommentInfo(CommentKind::CK_TextComment, {}, "This is a text comment.")};
CommentInfo ExpectedPara[] = {
CommentInfo(CommentKind::CK_ParagraphComment, ExpectedText)};
- CommentInfo TopE(CommentKind::CK_FullComment, ExpectedPara);
- Expected.Description.push_back(TopE);
+ Expected->Description.emplace_back(CommentKind::CK_FullComment, ExpectedPara);
auto Actual = mergeInfos(Infos);
assert(Actual);
- CheckFunctionInfo(InfoAsFunction(&Expected), InfoAsFunction(Actual.get()));
+ CheckFunctionInfo(InfoAsFunction(Expected.get()),
+ InfoAsFunction(Actual.get().get()));
}
TEST_F(MergeTest, mergeEnumInfos) {
EnumInfo One;
One.Name = "e";
- Reference Ns1[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- One.Namespace = llvm::ArrayRef(Ns1);
+ One.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
One.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- One.Loc.push_back(Loc1);
+ One.Loc.emplace_back(12, 12, "test.cpp");
One.Scoped = true;
EnumInfo Two;
Two.Name = "e";
- Reference Ns2[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Two.Namespace = llvm::ArrayRef(Ns2);
+ Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Location Loc2(20, 20, "test.cpp");
- Two.Loc.push_back(Loc2);
+ Two.Loc.emplace_back(20, 20, "test.cpp");
- EnumValueInfo EV2[] = {EnumValueInfo("X"), EnumValueInfo("Y")};
- Two.Members = llvm::ArrayRef(EV2);
+ Two.Members.emplace_back("X");
+ Two.Members.emplace_back("Y");
OwningPtrVec<Info> Infos;
- Infos.push_back(&One);
- Infos.push_back(&Two);
+ Infos.emplace_back(allocatePtr<EnumInfo>(std::move(One)));
+ Infos.emplace_back(allocatePtr<EnumInfo>(std::move(Two)));
- EnumInfo Expected;
- Expected.Name = "e";
- Reference NsE[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- Expected.Namespace = llvm::ArrayRef(NsE);
+ auto Expected = allocatePtr<EnumInfo>();
+ Expected->Name = "e";
+ Expected->Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Expected.DefLoc = Location(10, 10, "test.cpp");
- Location LocE1(12, 12, "test.cpp");
- Expected.Loc.push_back(LocE1);
- Location LocE2(20, 20, "test.cpp");
- Expected.Loc.push_back(LocE2);
+ Expected->DefLoc = Location(10, 10, "test.cpp");
+ Expected->Loc.emplace_back(12, 12, "test.cpp");
+ Expected->Loc.emplace_back(20, 20, "test.cpp");
- EnumValueInfo EV_E[] = {EnumValueInfo("X"), EnumValueInfo("Y")};
- Expected.Members = llvm::ArrayRef(EV_E);
- Expected.Scoped = true;
+ Expected->Members.emplace_back("X");
+ Expected->Members.emplace_back("Y");
+ Expected->Scoped = true;
auto Actual = mergeInfos(Infos);
assert(Actual);
- CheckEnumInfo(InfoAsEnum(&Expected), InfoAsEnum(Actual.get()));
+ CheckEnumInfo(InfoAsEnum(Expected.get()), InfoAsEnum(Actual.get().get()));
}
} // namespace doc
diff --git a/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp b/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
index 371efab1b3081..4e963fd64f11b 100644
--- a/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/SerializeTest.cpp
@@ -117,27 +117,25 @@ TEST_F(SerializeTest, emitNamespaceInfo) {
extractInfosFromCode("namespace A { namespace B { void f() {} } }", 5,
/*Public=*/false, Infos, this->Diags);
- NamespaceInfo *A = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *A = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedA(EmptySID, "A");
CheckNamespaceInfo(&ExpectedA, A);
- NamespaceInfo *B = InfoAsNamespace(Infos[2]);
+ NamespaceInfo *B = InfoAsNamespace(Infos[2].get());
NamespaceInfo ExpectedB(EmptySID, /*Name=*/"B", /*Path=*/"A");
- Reference NsB[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- ExpectedB.Namespace = llvm::ArrayRef(NsB);
+ ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
CheckNamespaceInfo(&ExpectedB, B);
- NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[4]);
+ NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[4].get());
NamespaceInfo ExpectedBWithFunction(EmptySID);
FunctionInfo F;
F.Name = "f";
F.ReturnType = TypeInfo("void");
F.DefLoc = Location(0, 0, "test.cpp");
- Reference NsF[] = {Reference(EmptySID, "B", InfoType::IT_namespace),
- Reference(EmptySID, "A", InfoType::IT_namespace)};
- F.Namespace = llvm::ArrayRef(NsF);
+ F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace);
+ F.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
F.Access = AccessSpecifier::AS_none;
- ExpectedBWithFunction.Children.Functions.push_back(F);
+ ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
}
@@ -146,7 +144,7 @@ TEST_F(SerializeTest, emitAnonymousNamespaceInfo) {
extractInfosFromCode("namespace { }", 2, /*Public=*/false, Infos,
this->Diags);
- NamespaceInfo *A = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *A = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedA(EmptySID);
ExpectedA.Name = "@nonymous_namespace";
CheckNamespaceInfo(&ExpectedA, A);
@@ -172,103 +170,95 @@ void F<int>::TemplateMethod();
typedef struct {} G;)raw",
10, /*Public=*/false, Infos, this->Diags);
- RecordInfo *E = InfoAsRecord(Infos[0]);
+ RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
- Reference NsE[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedE.Namespace = llvm::ArrayRef(NsE);
+ ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedE.TagType = TagTypeKind::Class;
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
- MemberTypeInfo MemE[] = {
- MemberTypeInfo(TypeInfo("int"), "value", AccessSpecifier::AS_public)};
- ExpectedE.Members = llvm::ArrayRef(MemE);
+ ExpectedE.Members.emplace_back(TypeInfo("int"), "value",
+ AccessSpecifier::AS_public);
// TODO the data member should have the docstring on it:
//ExpectedE.Members.back().Description.push_back(MakeOneLineCommentInfo(" Some docs"));
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[2]);
+ RecordInfo *RecordWithEConstructor = InfoAsRecord(Infos[2].get());
RecordInfo ExpectedRecordWithEConstructor(EmptySID);
FunctionInfo EConstructor;
EConstructor.Name = "E";
EConstructor.Parent = Reference(EmptySID, "E", InfoType::IT_record);
EConstructor.ReturnType = TypeInfo("void");
EConstructor.DefLoc = Location(0, 0, "test.cpp");
- Reference NsEC[] = {
- Reference(EmptySID, "E", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- EConstructor.Namespace = llvm::ArrayRef(NsEC);
+ EConstructor.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
+ EConstructor.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
EConstructor.Access = AccessSpecifier::AS_public;
EConstructor.IsMethod = true;
- ExpectedRecordWithEConstructor.Children.Functions.push_back(EConstructor);
+ ExpectedRecordWithEConstructor.Children.Functions.emplace_back(
+ std::move(EConstructor));
CheckRecordInfo(&ExpectedRecordWithEConstructor, RecordWithEConstructor);
- RecordInfo *RecordWithMethod = InfoAsRecord(Infos[3]);
+ RecordInfo *RecordWithMethod = InfoAsRecord(Infos[3].get());
RecordInfo ExpectedRecordWithMethod(EmptySID);
FunctionInfo Method;
Method.Name = "ProtectedMethod";
Method.Parent = Reference(EmptySID, "E", InfoType::IT_record);
Method.ReturnType = TypeInfo("void");
- Location LMethod(0, 0, "test.cpp");
- Method.Loc.push_back(LMethod);
- Reference NsMethod[] = {
- Reference(EmptySID, "E", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- Method.Namespace = llvm::ArrayRef(NsMethod);
+ Method.Loc.emplace_back(0, 0, "test.cpp");
+ Method.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
+ Method.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
Method.Access = AccessSpecifier::AS_protected;
Method.IsMethod = true;
- ExpectedRecordWithMethod.Children.Functions.push_back(Method);
+ ExpectedRecordWithMethod.Children.Functions.emplace_back(std::move(Method));
CheckRecordInfo(&ExpectedRecordWithMethod, RecordWithMethod);
- RecordInfo *F = InfoAsRecord(Infos[4]);
+ RecordInfo *F = InfoAsRecord(Infos[4].get());
RecordInfo ExpectedF(EmptySID, /*Name=*/"F", /*Path=*/"GlobalNamespace");
- Reference NsF3[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedF.Namespace = llvm::ArrayRef(NsF3);
+ ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedF.TagType = TagTypeKind::Struct;
ExpectedF.DefLoc = Location(0, 0, "test.cpp");
CheckRecordInfo(&ExpectedF, F);
- RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[6]);
+ RecordInfo *RecordWithTemplateMethod = InfoAsRecord(Infos[6].get());
RecordInfo ExpectedRecordWithTemplateMethod(EmptySID);
FunctionInfo TemplateMethod;
TemplateMethod.Name = "TemplateMethod";
TemplateMethod.Parent = Reference(EmptySID, "F", InfoType::IT_record);
TemplateMethod.ReturnType = TypeInfo("void");
- Location LTemp1(0, 0, "test.cpp");
- TemplateMethod.Loc.push_back(LTemp1);
- Reference NsT1[] = {
- Reference(EmptySID, "F", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- TemplateMethod.Namespace = llvm::ArrayRef(NsT1);
+ TemplateMethod.Loc.emplace_back(0, 0, "test.cpp");
+ TemplateMethod.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record);
+ TemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
TemplateMethod.Access = AccessSpecifier::AS_public;
TemplateMethod.IsMethod = true;
- ExpectedRecordWithTemplateMethod.Children.Functions.push_back(TemplateMethod);
+ ExpectedRecordWithTemplateMethod.Children.Functions.emplace_back(
+ std::move(TemplateMethod));
CheckRecordInfo(&ExpectedRecordWithTemplateMethod, RecordWithTemplateMethod);
- RecordInfo *TemplatedRecord = InfoAsRecord(Infos[7]);
+ RecordInfo *TemplatedRecord = InfoAsRecord(Infos[7].get());
RecordInfo ExpectedTemplatedRecord(EmptySID);
FunctionInfo SpecializedTemplateMethod;
SpecializedTemplateMethod.Name = "TemplateMethod";
SpecializedTemplateMethod.Parent =
Reference(EmptySID, "F", InfoType::IT_record);
SpecializedTemplateMethod.ReturnType = TypeInfo("void");
- Location LTemp2(0, 0, "test.cpp");
- SpecializedTemplateMethod.Loc.push_back(LTemp2);
- Reference NsT2[] = {
- Reference(EmptySID, "F", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- SpecializedTemplateMethod.Namespace = llvm::ArrayRef(NsT2);
+ SpecializedTemplateMethod.Loc.emplace_back(0, 0, "test.cpp");
+ SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "F",
+ InfoType::IT_record);
+ SpecializedTemplateMethod.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
SpecializedTemplateMethod.Access = AccessSpecifier::AS_public;
SpecializedTemplateMethod.IsMethod = true;
- ExpectedTemplatedRecord.Children.Functions.push_back(
- SpecializedTemplateMethod);
+ ExpectedTemplatedRecord.Children.Functions.emplace_back(
+ std::move(SpecializedTemplateMethod));
CheckRecordInfo(&ExpectedTemplatedRecord, TemplatedRecord);
- RecordInfo *G = InfoAsRecord(Infos[8]);
+ RecordInfo *G = InfoAsRecord(Infos[8].get());
RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/"GlobalNamespace");
- Reference NsG[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedG.Namespace = llvm::ArrayRef(NsG);
+ ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedG.TagType = TagTypeKind::Struct;
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
ExpectedG.IsTypeDef = true;
@@ -281,25 +271,25 @@ TEST_F(SerializeTest, emitEnumInfo) {
extractInfosFromCode("enum E { X, Y }; enum class G { A, B };", 2,
/*Public=*/false, Infos, this->Diags);
- NamespaceInfo *NamespaceWithEnum = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *NamespaceWithEnum = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedNamespaceWithEnum(EmptySID);
EnumInfo E;
E.Name = "E";
E.DefLoc = Location(0, 0, "test.cpp");
- EnumValueInfo EMem[] = {EnumValueInfo("X", "0"), EnumValueInfo("Y", "1")};
- E.Members = llvm::ArrayRef(EMem);
- ExpectedNamespaceWithEnum.Children.Enums.push_back(E);
+ E.Members.emplace_back("X", "0");
+ E.Members.emplace_back("Y", "1");
+ ExpectedNamespaceWithEnum.Children.Enums.emplace_back(std::move(E));
CheckNamespaceInfo(&ExpectedNamespaceWithEnum, NamespaceWithEnum);
- NamespaceInfo *NamespaceWithScopedEnum = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *NamespaceWithScopedEnum = InfoAsNamespace(Infos[1].get());
NamespaceInfo ExpectedNamespaceWithScopedEnum(EmptySID);
EnumInfo G;
G.Name = "G";
G.Scoped = true;
G.DefLoc = Location(0, 0, "test.cpp");
- EnumValueInfo GMem[] = {EnumValueInfo("A", "0"), EnumValueInfo("B", "1")};
- G.Members = llvm::ArrayRef(GMem);
- ExpectedNamespaceWithScopedEnum.Children.Enums.push_back(G);
+ G.Members.emplace_back("A", "0");
+ G.Members.emplace_back("B", "1");
+ ExpectedNamespaceWithScopedEnum.Children.Enums.emplace_back(std::move(G));
CheckNamespaceInfo(&ExpectedNamespaceWithScopedEnum, NamespaceWithScopedEnum);
}
@@ -307,14 +297,12 @@ TEST_F(SerializeTest, emitUndefinedRecordInfo) {
EmittedInfoList Infos;
extractInfosFromCode("class E;", 2, /*Public=*/false, Infos, this->Diags);
- RecordInfo *E = InfoAsRecord(Infos[0]);
+ RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
- Reference NsE[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedE.Namespace = llvm::ArrayRef(NsE);
+ ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedE.TagType = TagTypeKind::Class;
- Location LE(0, 0, "test.cpp");
- ExpectedE.Loc.push_back(LE);
+ ExpectedE.Loc.emplace_back(0, 0, "test.cpp");
CheckRecordInfo(&ExpectedE, E);
}
@@ -323,16 +311,14 @@ TEST_F(SerializeTest, emitRecordMemberInfo) {
extractInfosFromCode("struct E { int I; };", 2, /*Public=*/false, Infos,
this->Diags);
- RecordInfo *E = InfoAsRecord(Infos[0]);
+ RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
- Reference NsE[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedE.Namespace = llvm::ArrayRef(NsE);
+ ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedE.TagType = TagTypeKind::Struct;
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
- MemberTypeInfo MemE[] = {
- MemberTypeInfo(TypeInfo("int"), "I", AccessSpecifier::AS_public)};
- ExpectedE.Members = llvm::ArrayRef(MemE);
+ ExpectedE.Members.emplace_back(TypeInfo("int"), "I",
+ AccessSpecifier::AS_public);
CheckRecordInfo(&ExpectedE, E);
}
@@ -341,25 +327,23 @@ TEST_F(SerializeTest, emitInternalRecordInfo) {
extractInfosFromCode("class E { class G {}; };", 4, /*Public=*/false, Infos,
this->Diags);
- RecordInfo *E = InfoAsRecord(Infos[0]);
+ RecordInfo *E = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
- Reference NsE[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedE.Namespace = llvm::ArrayRef(NsE);
+ ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
ExpectedE.TagType = TagTypeKind::Class;
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *G = InfoAsRecord(Infos[2]);
+ RecordInfo *G = InfoAsRecord(Infos[2].get());
llvm::SmallString<128> ExpectedGPath("GlobalNamespace/E");
llvm::sys::path::native(ExpectedGPath);
RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/ExpectedGPath);
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
ExpectedG.TagType = TagTypeKind::Class;
- Reference NsG[] = {
- Reference(EmptySID, "E", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedG.Namespace = llvm::ArrayRef(NsG);
+ ExpectedG.Namespace.emplace_back(EmptySID, "E", InfoType::IT_record);
+ ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
CheckRecordInfo(&ExpectedG, G);
}
@@ -374,14 +358,14 @@ TEST_F(SerializeTest, emitPublicFunctionInternalInfo) {
extractInfosFromCode("int F() { class G {}; return 0; };", 1, /*Public=*/true,
Infos, this->Diags);
- NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedBWithFunction(EmptySID);
FunctionInfo F;
F.Name = "F";
F.ReturnType = TypeInfo("int");
F.DefLoc = Location(0, 0, "test.cpp");
F.Access = AccessSpecifier::AS_none;
- ExpectedBWithFunction.Children.Functions.push_back(F);
+ ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
}
@@ -390,16 +374,15 @@ TEST_F(SerializeTest, emitInlinedFunctionInfo) {
extractInfosFromCode("inline void F(int I) { };", 1, /*Public=*/true, Infos,
this->Diags);
- NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedBWithFunction(EmptySID);
FunctionInfo F;
F.Name = "F";
F.ReturnType = TypeInfo("void");
F.DefLoc = Location(0, 0, "test.cpp");
- FieldTypeInfo Params[] = {FieldTypeInfo(TypeInfo("int"), "I")};
- F.Params = llvm::ArrayRef(Params);
+ F.Params.emplace_back(TypeInfo("int"), "I");
F.Access = AccessSpecifier::AS_none;
- ExpectedBWithFunction.Children.Functions.push_back(F);
+ ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
}
@@ -414,169 +397,132 @@ class I {} ;
class J : public I<int> {} ;)raw",
14, /*Public=*/false, Infos, this->Diags);
- RecordInfo *F = InfoAsRecord(Infos[0]);
+ RecordInfo *F = InfoAsRecord(Infos[0].get());
RecordInfo ExpectedF(EmptySID, /*Name=*/"F", /*Path=*/"GlobalNamespace");
- Reference NsF[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedF.Namespace = llvm::ArrayRef(NsF);
+ ExpectedF.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace, "");
ExpectedF.TagType = TagTypeKind::Class;
ExpectedF.DefLoc = Location(0, 0, "test.cpp");
CheckRecordInfo(&ExpectedF, F);
- RecordInfo *G = InfoAsRecord(Infos[3]);
+ RecordInfo *G = InfoAsRecord(Infos[3].get());
RecordInfo ExpectedG(EmptySID, /*Name=*/"G", /*Path=*/"GlobalNamespace");
- Reference NsG[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedG.Namespace = llvm::ArrayRef(NsG);
+ ExpectedG.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedG.TagType = TagTypeKind::Class;
ExpectedG.DefLoc = Location(0, 0, "test.cpp");
- MemberTypeInfo MemG[] = {
- MemberTypeInfo(TypeInfo("int"), "I", AccessSpecifier::AS_protected)};
- ExpectedG.Members = llvm::ArrayRef(MemG);
+ ExpectedG.Members.emplace_back(TypeInfo("int"), "I",
+ AccessSpecifier::AS_protected);
CheckRecordInfo(&ExpectedG, G);
- RecordInfo *E = InfoAsRecord(Infos[6]);
+ RecordInfo *E = InfoAsRecord(Infos[6].get());
RecordInfo ExpectedE(EmptySID, /*Name=*/"E", /*Path=*/"GlobalNamespace");
- Reference NsE[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedE.Namespace = llvm::ArrayRef(NsE);
- Reference ParE[] = {Reference(EmptySID, /*Name=*/"F", InfoType::IT_record,
- /*QualName=*/"", /*Path=*/"GlobalNamespace")};
- ExpectedE.Parents = llvm::ArrayRef(ParE);
- Reference VParE[] = {Reference(EmptySID, /*Name=*/"G", InfoType::IT_record,
- /*QualName=*/"G",
- /*Path=*/"GlobalNamespace")};
- ExpectedE.VirtualParents = llvm::ArrayRef(VParE);
- BaseRecordInfo BaseF(EmptySID, /*Name=*/"F",
- /*Path=*/"GlobalNamespace", false,
- AccessSpecifier::AS_public, true);
+ ExpectedE.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
+ ExpectedE.Parents.emplace_back(EmptySID, /*Name=*/"F", InfoType::IT_record,
+ /*QualName=*/"", /*Path*=*/"GlobalNamespace");
+ ExpectedE.VirtualParents.emplace_back(EmptySID, /*Name=*/"G",
+ InfoType::IT_record, /*QualName=*/"G",
+ /*Path*=*/"GlobalNamespace");
+ ExpectedE.Bases.emplace_back(EmptySID, /*Name=*/"F",
+ /*Path=*/"GlobalNamespace", false,
+ AccessSpecifier::AS_public, true);
FunctionInfo FunctionSet;
FunctionSet.Name = "set";
FunctionSet.ReturnType = TypeInfo("void");
- Location LSet;
- FunctionSet.Loc.push_back(LSet);
- FieldTypeInfo ParamsSet[] = {FieldTypeInfo(TypeInfo("int"), "N")};
- FunctionSet.Params = llvm::ArrayRef(ParamsSet);
- Reference NsSet[] = {
- Reference(EmptySID, "F", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- FunctionSet.Namespace = llvm::ArrayRef(NsSet);
- FunctionSet.Access =
- AccessSpecifier::AS_none; // Wait, previous had AS_protected, but wait,
- // F.Access was AS_protected. FunctionSet.Access
- // should be AS_protected if it was so. In the
- // original it was AS_protected.
+ FunctionSet.Loc.emplace_back();
+ FunctionSet.Params.emplace_back(TypeInfo("int"), "N");
+ FunctionSet.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record);
+ FunctionSet.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
FunctionSet.Access = AccessSpecifier::AS_protected;
FunctionSet.IsMethod = true;
- BaseF.Children.Functions.push_back(FunctionSet);
-
- BaseRecordInfo BaseG(EmptySID, /*Name=*/"G",
- /*Path=*/"GlobalNamespace", true,
- AccessSpecifier::AS_private, true);
+ ExpectedE.Bases.back().Children.Functions.emplace_back(
+ std::move(FunctionSet));
+ ExpectedE.Bases.emplace_back(EmptySID, /*Name=*/"G",
+ /*Path=*/"GlobalNamespace", true,
+ AccessSpecifier::AS_private, true);
FunctionInfo FunctionGet;
FunctionGet.Name = "get";
FunctionGet.ReturnType = TypeInfo("int");
- Location LGet;
- FunctionGet.DefLoc = LGet;
- Reference NsGet[] = {
- Reference(EmptySID, "G", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- FunctionGet.Namespace = llvm::ArrayRef(NsGet);
+ FunctionGet.DefLoc = Location();
+ FunctionGet.Namespace.emplace_back(EmptySID, "G", InfoType::IT_record);
+ FunctionGet.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
FunctionGet.Access = AccessSpecifier::AS_private;
FunctionGet.IsMethod = true;
- BaseG.Children.Functions.push_back(FunctionGet);
- MemberTypeInfo MemG2[] = {
- MemberTypeInfo(TypeInfo("int"), "I", AccessSpecifier::AS_private)};
- BaseG.Members = llvm::ArrayRef(MemG2);
-
- BaseRecordInfo BasesE[] = {std::move(BaseF), std::move(BaseG)};
- ExpectedE.Bases = llvm::ArrayRef(BasesE);
+ ExpectedE.Bases.back().Children.Functions.emplace_back(
+ std::move(FunctionGet));
+ ExpectedE.Bases.back().Members.emplace_back(TypeInfo("int"), "I",
+ AccessSpecifier::AS_private);
ExpectedE.DefLoc = Location(0, 0, "test.cpp");
ExpectedE.TagType = TagTypeKind::Class;
CheckRecordInfo(&ExpectedE, E);
- RecordInfo *H = InfoAsRecord(Infos[8]);
+ RecordInfo *H = InfoAsRecord(Infos[8].get());
RecordInfo ExpectedH(EmptySID, /*Name=*/"H", /*Path=*/"GlobalNamespace");
- Reference NsH[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedH.Namespace = llvm::ArrayRef(NsH);
+ ExpectedH.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedH.TagType = TagTypeKind::Class;
ExpectedH.DefLoc = Location(0, 0, "test.cpp");
- Reference ParH[] = {Reference(EmptySID, /*Name=*/"E", InfoType::IT_record,
- /*QualName=*/"E", /*Path=*/"GlobalNamespace")};
- ExpectedH.Parents = llvm::ArrayRef(ParH);
- Reference VParH[] = {Reference(EmptySID, /*Name=*/"G", InfoType::IT_record,
- /*QualName=*/"G",
- /*Path=*/"GlobalNamespace")};
- ExpectedH.VirtualParents = llvm::ArrayRef(VParH);
-
- BaseRecordInfo BaseHE(EmptySID, /*Name=*/"E",
- /*Path=*/"GlobalNamespace", false,
- AccessSpecifier::AS_private, true);
-
- BaseRecordInfo BaseHF(EmptySID, /*Name=*/"F",
- /*Path=*/"GlobalNamespace", false,
- AccessSpecifier::AS_private, false);
+ ExpectedH.Parents.emplace_back(EmptySID, /*Name=*/"E", InfoType::IT_record,
+ /*QualName=*/"E", /*Path=*/"GlobalNamespace");
+ ExpectedH.VirtualParents.emplace_back(EmptySID, /*Name=*/"G",
+ InfoType::IT_record, /*QualName=*/"G",
+ /*Path=*/"GlobalNamespace");
+ ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"E",
+ /*Path=*/"GlobalNamespace", false,
+ AccessSpecifier::AS_private, true);
+ ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"F",
+ /*Path=*/"GlobalNamespace", false,
+ AccessSpecifier::AS_private, false);
FunctionInfo FunctionSetNew;
FunctionSetNew.Name = "set";
FunctionSetNew.ReturnType = TypeInfo("void");
- Location LSetNew;
- FunctionSetNew.Loc.push_back(LSetNew);
- FieldTypeInfo ParamsSetNew[] = {FieldTypeInfo(TypeInfo("int"), "N")};
- FunctionSetNew.Params = llvm::ArrayRef(ParamsSetNew);
- Reference NsSetNew[] = {
- Reference(EmptySID, "F", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- FunctionSetNew.Namespace = llvm::ArrayRef(NsSetNew);
+ FunctionSetNew.Loc.emplace_back();
+ FunctionSetNew.Params.emplace_back(TypeInfo("int"), "N");
+ FunctionSetNew.Namespace.emplace_back(EmptySID, "F", InfoType::IT_record);
+ FunctionSetNew.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
FunctionSetNew.Access = AccessSpecifier::AS_private;
FunctionSetNew.IsMethod = true;
- BaseHF.Children.Functions.push_back(FunctionSetNew);
- BaseRecordInfo BaseHG(EmptySID, /*Name=*/"G",
- /*Path=*/"GlobalNamespace", true,
- AccessSpecifier::AS_private, false);
+ ExpectedH.Bases.back().Children.Functions.emplace_back(
+ std::move(FunctionSetNew));
+ ExpectedH.Bases.emplace_back(EmptySID, /*Name=*/"G",
+ /*Path=*/"GlobalNamespace", true,
+ AccessSpecifier::AS_private, false);
FunctionInfo FunctionGetNew;
FunctionGetNew.Name = "get";
FunctionGetNew.ReturnType = TypeInfo("int");
- Location LGetNew;
- FunctionGetNew.DefLoc = LGetNew;
- Reference NsGetNew[] = {
- Reference(EmptySID, "G", InfoType::IT_record),
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- FunctionGetNew.Namespace = llvm::ArrayRef(NsGetNew);
+ FunctionGetNew.DefLoc = Location();
+ FunctionGetNew.Namespace.emplace_back(EmptySID, "G", InfoType::IT_record);
+ FunctionGetNew.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
FunctionGetNew.Access = AccessSpecifier::AS_private;
FunctionGetNew.IsMethod = true;
- BaseHG.Children.Functions.push_back(FunctionGetNew);
- MemberTypeInfo MemHG[] = {
- MemberTypeInfo(TypeInfo("int"), "I", AccessSpecifier::AS_private)};
- BaseHG.Members = llvm::ArrayRef(MemHG);
-
- BaseRecordInfo BasesH[] = {std::move(BaseHE), std::move(BaseHF),
- std::move(BaseHG)};
- ExpectedH.Bases = llvm::ArrayRef(BasesH);
-
+ ExpectedH.Bases.back().Children.Functions.emplace_back(
+ std::move(FunctionGetNew));
+ ExpectedH.Bases.back().Members.emplace_back(TypeInfo("int"), "I",
+ AccessSpecifier::AS_private);
CheckRecordInfo(&ExpectedH, H);
- RecordInfo *I = InfoAsRecord(Infos[10]);
+ RecordInfo *I = InfoAsRecord(Infos[10].get());
RecordInfo ExpectedI(EmptySID, /*Name=*/"I", /*Path=*/"GlobalNamespace");
- Reference NsI[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedI.Namespace = llvm::ArrayRef(NsI);
+ ExpectedI.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
ExpectedI.TagType = TagTypeKind::Class;
ExpectedI.DefLoc = Location(0, 0, "test.cpp");
CheckRecordInfo(&ExpectedI, I);
- RecordInfo *J = InfoAsRecord(Infos[12]);
+ RecordInfo *J = InfoAsRecord(Infos[12].get());
RecordInfo ExpectedJ(EmptySID, /*Name=*/"J", /*Path=*/"GlobalNamespace");
- Reference NsJ[] = {
- Reference(EmptySID, "GlobalNamespace", InfoType::IT_namespace)};
- ExpectedJ.Namespace = llvm::ArrayRef(NsJ);
- Reference ParJ[] = {
- Reference(EmptySID, /*Name=*/"I<int>", InfoType::IT_record)};
- ExpectedJ.Parents = llvm::ArrayRef(ParJ);
- BaseRecordInfo BasesJ[] = {BaseRecordInfo(EmptySID, /*Name=*/"I<int>",
- /*Path=*/"GlobalNamespace", false,
- AccessSpecifier::AS_public, true)};
- ExpectedJ.Bases = llvm::ArrayRef(BasesJ);
+ ExpectedJ.Namespace.emplace_back(EmptySID, "GlobalNamespace",
+ InfoType::IT_namespace);
+ ExpectedJ.Parents.emplace_back(EmptySID, /*Name=*/"I<int>",
+ InfoType::IT_record);
+ ExpectedJ.Bases.emplace_back(EmptySID, /*Name=*/"I<int>",
+ /*Path=*/"GlobalNamespace", false,
+ AccessSpecifier::AS_public, true);
ExpectedJ.DefLoc = Location(0, 0, "test.cpp");
ExpectedJ.TagType = TagTypeKind::Class;
CheckRecordInfo(&ExpectedJ, J);
@@ -592,33 +538,30 @@ static int staticModuleFunction(int x);
export double exportedModuleFunction(double y);)raw",
2, /*Public=*/true, Infos, Args, this->Diags);
- NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[0].get());
NamespaceInfo ExpectedBWithFunction(EmptySID);
FunctionInfo F;
F.Name = "moduleFunction";
F.ReturnType = TypeInfo("int");
- Location LF1(0, 0, "test.cpp");
- F.Loc.push_back(LF1);
- FieldTypeInfo ParamsF[] = {FieldTypeInfo(TypeInfo("int"), "x"),
- FieldTypeInfo(TypeInfo("double"), "d")};
- ParamsF[1].DefaultValue = "3.2 - 1.0";
- F.Params = llvm::ArrayRef(ParamsF);
+ F.Loc.emplace_back(0, 0, "test.cpp");
+ F.Params.emplace_back(TypeInfo("int"), "x");
+ F.Params.emplace_back(TypeInfo("double"), "d");
+ F.Params.back().DefaultValue = "3.2 - 1.0";
F.Access = AccessSpecifier::AS_none;
- ExpectedBWithFunction.Children.Functions.push_back(F);
+ ExpectedBWithFunction.Children.Functions.emplace_back(std::move(F));
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
- NamespaceInfo *BWithExportedFunction = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *BWithExportedFunction = InfoAsNamespace(Infos[1].get());
NamespaceInfo ExpectedBWithExportedFunction(EmptySID);
FunctionInfo ExportedF;
ExportedF.Name = "exportedModuleFunction";
ExportedF.ReturnType =
TypeInfo(Reference(EmptySID, "double", InfoType::IT_default));
- Location LF2(0, 0, "test.cpp");
- ExportedF.Loc.push_back(LF2);
- FieldTypeInfo ParamsExportedF[] = {FieldTypeInfo(TypeInfo("double"), "y")};
- ExportedF.Params = llvm::ArrayRef(ParamsExportedF);
+ ExportedF.Loc.emplace_back(0, 0, "test.cpp");
+ ExportedF.Params.emplace_back(TypeInfo("double"), "y");
ExportedF.Access = AccessSpecifier::AS_none;
- ExpectedBWithExportedFunction.Children.Functions.push_back(ExportedF);
+ ExpectedBWithExportedFunction.Children.Functions.emplace_back(
+ std::move(ExportedF));
CheckNamespaceInfo(&ExpectedBWithExportedFunction, BWithExportedFunction);
}
@@ -628,24 +571,24 @@ TEST_F(SerializeTest, emitChildRecords) {
extractInfosFromCode("class A { class B {}; }; namespace { class C {}; } ", 8,
/*Public=*/false, Infos, this->Diags);
- NamespaceInfo *ParentA = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get());
NamespaceInfo ExpectedParentA(EmptySID);
- Reference RA(EmptySID, "A", InfoType::IT_record, "A", "GlobalNamespace");
- ExpectedParentA.Children.Records.push_back(RA);
+ ExpectedParentA.Children.Records.emplace_back(
+ EmptySID, "A", InfoType::IT_record, "A", "GlobalNamespace");
CheckNamespaceInfo(&ExpectedParentA, ParentA);
- RecordInfo *ParentB = InfoAsRecord(Infos[3]);
+ RecordInfo *ParentB = InfoAsRecord(Infos[3].get());
RecordInfo ExpectedParentB(EmptySID);
llvm::SmallString<128> ExpectedParentBPath("GlobalNamespace/A");
llvm::sys::path::native(ExpectedParentBPath);
- Reference RB(EmptySID, "B", InfoType::IT_record, "A::B", ExpectedParentBPath);
- ExpectedParentB.Children.Records.push_back(RB);
+ ExpectedParentB.Children.Records.emplace_back(
+ EmptySID, "B", InfoType::IT_record, "A::B", ExpectedParentBPath);
CheckRecordInfo(&ExpectedParentB, ParentB);
- NamespaceInfo *ParentC = InfoAsNamespace(Infos[7]);
+ NamespaceInfo *ParentC = InfoAsNamespace(Infos[7].get());
NamespaceInfo ExpectedParentC(EmptySID);
- Reference RC(EmptySID, "C", InfoType::IT_record, "C", "@nonymous_namespace");
- ExpectedParentC.Children.Records.push_back(RC);
+ ExpectedParentC.Children.Records.emplace_back(
+ EmptySID, "C", InfoType::IT_record, "C", "@nonymous_namespace");
CheckNamespaceInfo(&ExpectedParentC, ParentC);
}
@@ -655,13 +598,13 @@ TEST_F(SerializeTest, emitChildNamespaces) {
extractInfosFromCode("namespace A { namespace B { } }", 4, /*Public=*/false,
Infos, this->Diags);
- NamespaceInfo *ParentA = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *ParentA = InfoAsNamespace(Infos[1].get());
NamespaceInfo ExpectedParentA(EmptySID);
Reference RA(EmptySID, "A", InfoType::IT_namespace);
ExpectedParentA.Children.Namespaces.push_back(RA);
CheckNamespaceInfo(&ExpectedParentA, ParentA);
- NamespaceInfo *ParentB = InfoAsNamespace(Infos[3]);
+ NamespaceInfo *ParentB = InfoAsNamespace(Infos[3].get());
NamespaceInfo ExpectedParentB(EmptySID);
Reference RB(EmptySID, "B", InfoType::IT_namespace, "A::B", "A");
ExpectedParentB.Children.Namespaces.push_back(RB);
@@ -674,10 +617,10 @@ TEST_F(SerializeTest, emitTypedefs) {
/*Public=*/false, Infos, this->Diags);
// First info will be the global namespace with the typedef in it.
- NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0].get());
ASSERT_EQ(1u, GlobalNS1->Children.Typedefs.size());
- const TypedefInfo &FirstTD = *GlobalNS1->Children.Typedefs.begin();
+ const TypedefInfo &FirstTD = GlobalNS1->Children.Typedefs[0];
EXPECT_EQ("MyInt", FirstTD.Name);
EXPECT_FALSE(FirstTD.IsUsing);
EXPECT_EQ("int", FirstTD.Underlying.Type.Name);
@@ -685,11 +628,11 @@ TEST_F(SerializeTest, emitTypedefs) {
// The second will be another global namespace with the using in it (the
// global namespace is duplicated because the items haven't been merged at the
// serialization phase of processing).
- NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1].get());
ASSERT_EQ(1u, GlobalNS2->Children.Typedefs.size());
// Second is the "using" typedef.
- const TypedefInfo &SecondTD = *GlobalNS2->Children.Typedefs.begin();
+ const TypedefInfo &SecondTD = GlobalNS2->Children.Typedefs[0];
EXPECT_EQ("MyDouble", SecondTD.Name);
EXPECT_TRUE(SecondTD.IsUsing);
EXPECT_EQ("double", SecondTD.Underlying.Type.Name);
@@ -704,10 +647,10 @@ TEST_F(SerializeTest, emitFunctionTemplate) {
/*Public=*/false, Infos, this->Diags);
// First info will be the global namespace.
- NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0]);
+ NamespaceInfo *GlobalNS1 = InfoAsNamespace(Infos[0].get());
ASSERT_EQ(1u, GlobalNS1->Children.Functions.size());
- const FunctionInfo &Func1 = *GlobalNS1->Children.Functions.begin();
+ const FunctionInfo &Func1 = GlobalNS1->Children.Functions[0];
EXPECT_EQ("GetFoo", Func1.Name);
ASSERT_TRUE(Func1.Template);
EXPECT_FALSE(Func1.Template->Specialization); // Not a specialization.
@@ -719,11 +662,11 @@ TEST_F(SerializeTest, emitFunctionTemplate) {
// The second will be another global namespace with the function in it (the
// global namespace is duplicated because the items haven't been merged at the
// serialization phase of processing).
- NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1]);
+ NamespaceInfo *GlobalNS2 = InfoAsNamespace(Infos[1].get());
ASSERT_EQ(1u, GlobalNS2->Children.Functions.size());
// This one is a template specialization.
- const FunctionInfo &Func2 = *GlobalNS2->Children.Functions.begin();
+ const FunctionInfo &Func2 = GlobalNS2->Children.Functions[0];
EXPECT_EQ("GetFoo", Func2.Name);
ASSERT_TRUE(Func2.Template);
EXPECT_TRUE(Func2.Template->Params.empty()); // No template params.
@@ -751,7 +694,7 @@ TEST_F(SerializeTest, emitClassTemplate) {
/*Public=*/false, Infos, this->Diags);
// First record.
- const RecordInfo *Rec1 = InfoAsRecord(Infos[0]);
+ const RecordInfo *Rec1 = InfoAsRecord(Infos[0].get());
EXPECT_EQ("MyTemplate", Rec1->Name);
ASSERT_TRUE(Rec1->Template);
EXPECT_FALSE(Rec1->Template->Specialization); // Not a specialization.
@@ -761,7 +704,7 @@ TEST_F(SerializeTest, emitClassTemplate) {
EXPECT_EQ("int I", Rec1->Template->Params[0].Contents);
// Second record.
- const RecordInfo *Rec2 = InfoAsRecord(Infos[2]);
+ const RecordInfo *Rec2 = InfoAsRecord(Infos[2].get());
EXPECT_EQ("MyTemplate", Rec2->Name);
ASSERT_TRUE(Rec2->Template);
EXPECT_TRUE(Rec2->Template->Params.empty()); // No template params.
@@ -773,7 +716,7 @@ TEST_F(SerializeTest, emitClassTemplate) {
EXPECT_EQ(Rec1->USR, Rec2->Template->Specialization->SpecializationOf);
// Third record.
- const RecordInfo *Rec3 = InfoAsRecord(Infos[4]);
+ const RecordInfo *Rec3 = InfoAsRecord(Infos[4].get());
EXPECT_EQ("OtherTemplate", Rec3->Name);
ASSERT_TRUE(Rec3->Template);
@@ -783,7 +726,7 @@ TEST_F(SerializeTest, emitClassTemplate) {
EXPECT_EQ("int U = 1", Rec3->Template->Params[1].Contents);
// Fourth record.
- const RecordInfo *Rec4 = InfoAsRecord(Infos[6]);
+ const RecordInfo *Rec4 = InfoAsRecord(Infos[6].get());
EXPECT_EQ("OtherTemplate", Rec3->Name);
ASSERT_TRUE(Rec4->Template);
ASSERT_TRUE(Rec4->Template->Specialization);
diff --git a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
index 6f4b724bd9427..a7f8629b926c1 100644
--- a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
@@ -28,25 +28,20 @@ TEST_F(YAMLGeneratorTest, emitNamespaceYAML) {
NamespaceInfo I;
I.Name = "Namespace";
I.Path = "path/to/A";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace,
"path::to::A::Namespace::ChildNamespace",
"path/to/A/Namespace");
I.Children.Namespaces.push_back(NewNamespace);
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
- "path::to::A::Namespace::ChildStruct",
- "path/to/A/Namespace");
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo F;
- F.Name = "OneFunction";
- F.Access = AccessSpecifier::AS_none;
- I.Children.Functions.push_back(F);
-
- EnumInfo E;
- E.Name = "OneEnum";
- I.Children.Enums.push_back(E);
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
+ "path::to::A::Namespace::ChildStruct",
+ "path/to/A/Namespace");
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
+ I.Children.Functions.back().Access = AccessSpecifier::AS_none;
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "OneEnum";
auto G = getYAMLGenerator();
assert(G);
@@ -90,14 +85,12 @@ TEST_F(YAMLGeneratorTest, emitRecordYAML) {
I.Name = "r";
I.Path = "path/to/A";
I.IsTypeDef = true;
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- MemberTypeInfo M(TypeInfo("int"), "X", AccessSpecifier::AS_private);
+ I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);
// Member documentation.
CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {},
@@ -106,39 +99,26 @@ TEST_F(YAMLGeneratorTest, emitRecordYAML) {
CommentInfo TopCommentChildren[] = {
CommentInfo(CommentKind::CK_ParagraphComment, BriefChildren)};
CommentInfo TopComment(CommentKind::CK_FullComment, TopCommentChildren);
- M.Description.push_back(TopComment);
- MemberTypeInfo MemArr[] = {std::move(M)};
- I.Members = llvm::ArrayRef(MemArr);
+ I.Members.back().Description.push_back(std::move(TopComment));
I.TagType = TagTypeKind::Class;
- BaseRecordInfo B(EmptySID, "F", "path/to/F", true, AccessSpecifier::AS_public,
- true);
- FunctionInfo F;
- F.Name = "InheritedFunctionOne";
- B.Children.Functions.push_back(F);
- MemberTypeInfo BMem[] = {
- MemberTypeInfo(TypeInfo("int"), "N", AccessSpecifier::AS_private)};
- B.Members = llvm::ArrayRef(BMem);
- BaseRecordInfo Bases[] = {std::move(B)};
- I.Bases = llvm::ArrayRef(Bases);
-
+ I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
+ AccessSpecifier::AS_public, true);
+ I.Bases.back().Children.Functions.emplace_back();
+ I.Bases.back().Children.Functions.back().Name = "InheritedFunctionOne";
+ I.Bases.back().Members.emplace_back(TypeInfo("int"), "N",
+ AccessSpecifier::AS_private);
// F is in the global namespace
- Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record, "")};
- I.Parents = llvm::ArrayRef(Parents);
- Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record,
- "path::to::G::G", "path/to/G")};
- I.VirtualParents = llvm::ArrayRef(VParents);
-
- Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
- "path::to::A::r::ChildStruct", "path/to/A/r");
- I.Children.Records.push_back(ChildStruct);
- FunctionInfo F2;
- F2.Name = "OneFunction";
- I.Children.Functions.push_back(F2);
-
- EnumInfo E;
- E.Name = "OneEnum";
- I.Children.Enums.push_back(E);
+ I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "");
+ I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record,
+ "path::to::G::G", "path/to/G");
+
+ I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
+ "path::to::A::r::ChildStruct", "path/to/A/r");
+ I.Children.Functions.emplace_back();
+ I.Children.Functions.back().Name = "OneFunction";
+ I.Children.Enums.emplace_back();
+ I.Children.Enums.back().Name = "OneEnum";
auto G = getYAMLGenerator();
assert(G);
@@ -225,22 +205,17 @@ IsTypeDef: true
TEST_F(YAMLGeneratorTest, emitFunctionYAML) {
FunctionInfo I;
I.Name = "f";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
I.Access = AccessSpecifier::AS_none;
I.ReturnType = TypeInfo(Reference(EmptySID, "void", InfoType::IT_default));
-
- FieldTypeInfo P1(TypeInfo("int"), "P");
- FieldTypeInfo D(TypeInfo("double"), "D");
- D.DefaultValue = "2.0 * M_PI";
- FieldTypeInfo Params[] = {std::move(P1), std::move(D)};
- I.Params = llvm::ArrayRef(Params);
+ I.Params.emplace_back(TypeInfo("int"), "P");
+ I.Params.emplace_back(TypeInfo("double"), "D");
+ I.Params.back().DefaultValue = "2.0 * M_PI";
I.IsMethod = true;
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
@@ -295,15 +270,12 @@ IsMethod: true
TEST_F(YAMLGeneratorTest, emitSimpleEnumYAML) {
EnumInfo I;
I.Name = "e";
- Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
- I.Namespace = llvm::ArrayRef(Ns);
+ I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
I.DefLoc = Location(10, 10, "test.cpp");
- Location Loc1(12, 12, "test.cpp");
- I.Loc.push_back(Loc1);
+ I.Loc.emplace_back(12, 12, "test.cpp");
- EnumValueInfo EV[] = {EnumValueInfo("X")};
- I.Members = llvm::ArrayRef(EV);
+ I.Members.emplace_back("X");
I.Scoped = false;
auto G = getYAMLGenerator();
@@ -340,8 +312,7 @@ TEST_F(YAMLGeneratorTest, enumTypedScopedEnumYAML) {
EnumInfo I;
I.Name = "e";
- EnumValueInfo EV[] = {EnumValueInfo("X", "-9876", "FOO_BAR + 2")};
- I.Members = llvm::ArrayRef(EV);
+ I.Members.emplace_back("X", "-9876", "FOO_BAR + 2");
I.Scoped = true;
I.BaseType = TypeInfo("short");
@@ -399,9 +370,8 @@ TEST_F(YAMLGeneratorTest, emitCommentYAML) {
I.Name = "f";
I.DefLoc = Location(10, 10, "test.cpp");
I.ReturnType = TypeInfo("void");
- FieldTypeInfo Params[] = {FieldTypeInfo(TypeInfo("int"), "I"),
- FieldTypeInfo(TypeInfo("int"), "J")};
- I.Params = llvm::ArrayRef(Params);
+ I.Params.emplace_back(TypeInfo("int"), "I");
+ I.Params.emplace_back(TypeInfo("int"), "J");
I.Access = AccessSpecifier::AS_none;
// BlankLine
@@ -474,7 +444,7 @@ TEST_F(YAMLGeneratorTest, emitCommentYAML) {
Verbatim, ParamOut, ParamIn, Return};
CommentInfo Top(CommentKind::CK_FullComment, TopChildren);
- I.Description.push_back(Top);
+ I.Description.emplace_back(std::move(Top));
auto G = getYAMLGenerator();
assert(G);
More information about the cfe-commits
mailing list