summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorJulie Hockett <juliehockett@google.com>2019-06-28 18:17:58 +0000
committerJulie Hockett <juliehockett@google.com>2019-06-28 18:17:58 +0000
commit93a290fdc974007ed3eeb7be11b527f66f43a01d (patch)
tree6766463e0c0dd43a823d88371459d84e1fc7b84a /clang-tools-extra
parent9db6073381da617bea6c117d02fd0b0d30d33c4b (diff)
downloadbcm5719-llvm-93a290fdc974007ed3eeb7be11b527f66f43a01d.tar.gz
bcm5719-llvm-93a290fdc974007ed3eeb7be11b527f66f43a01d.zip
[clang-doc] De-duplicate comments and locations
De-duplicate comments and declaration locations in reduce function. When two files include the same header file, this file's content is mapped twice causing comments and locations to be duplicated after the reduce stage. Committed on behalf of Diego Astiazarán (diegoaat97@gmail.com). Differential Revision: https://reviews.llvm.org/D62970 llvm-svn: 364670
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/clang-doc/Representation.cpp6
-rw-r--r--clang-tools-extra/clang-doc/Representation.h48
-rw-r--r--clang-tools-extra/unittests/clang-doc/MergeTest.cpp36
3 files changed, 88 insertions, 2 deletions
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index 398d1025e97..62c2d17c291 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -122,6 +122,9 @@ void Info::mergeBase(Info &&Other) {
// Unconditionally extend the description, since each decl may have a comment.
std::move(Other.Description.begin(), Other.Description.end(),
std::back_inserter(Description));
+ std::sort(Description.begin(), Description.end());
+ auto Last = std::unique(Description.begin(), Description.end());
+ Description.erase(Last, Description.end());
}
bool Info::mergeable(const Info &Other) {
@@ -134,6 +137,9 @@ void SymbolInfo::merge(SymbolInfo &&Other) {
DefLoc = std::move(Other.DefLoc);
// Unconditionally extend the list of locations, since we want all of them.
std::move(Other.Loc.begin(), Other.Loc.end(), std::back_inserter(Loc));
+ std::sort(Loc.begin(), Loc.end());
+ auto Last = std::unique(Loc.begin(), Loc.end());
+ Loc.erase(Last, Loc.end());
mergeBase(std::move(Other));
}
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index c5a643c65c4..0550cf03754 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -46,6 +46,45 @@ struct CommentInfo {
CommentInfo() = default;
CommentInfo(CommentInfo &Other) = delete;
CommentInfo(CommentInfo &&Other) = default;
+ CommentInfo &operator=(CommentInfo &&Other) = default;
+
+ bool operator==(const CommentInfo &Other) const {
+ auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName,
+ SelfClosing, Explicit, AttrKeys, AttrValues, Args);
+ auto SecondCI =
+ std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction,
+ Other.ParamName, Other.CloseName, Other.SelfClosing,
+ Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args);
+
+ if (FirstCI != SecondCI || Children.size() != Other.Children.size())
+ return false;
+
+ return std::equal(Children.begin(), Children.end(), Other.Children.begin(),
+ llvm::deref<llvm::equal>{});
+ }
+
+ // This operator is used to sort a vector of CommentInfos.
+ // No specific order (attributes more important than others) is required. Any
+ // sort is enough, the order is only needed to call std::unique after sorting
+ // the vector.
+ bool operator<(const CommentInfo &Other) const {
+ auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName,
+ SelfClosing, Explicit, AttrKeys, AttrValues, Args);
+ auto SecondCI =
+ std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction,
+ Other.ParamName, Other.CloseName, Other.SelfClosing,
+ Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args);
+
+ if (FirstCI < SecondCI ||
+ (FirstCI == SecondCI && Children.size() < Other.Children.size()))
+ return true;
+
+ if (FirstCI > SecondCI || Children.size() > Other.Children.size())
+ return false;
+
+ return std::equal(Children.begin(), Children.end(), Other.Children.begin(),
+ llvm::deref<llvm::less>{});
+ }
SmallString<16>
Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
@@ -148,6 +187,15 @@ struct Location {
std::tie(Other.LineNumber, Other.Filename);
}
+ // This operator is used to sort a vector of Locations.
+ // No specific order (attributes more important than others) is required. Any
+ // sort is enough, the order is only needed to call std::unique after sorting
+ // the vector.
+ bool operator<(const Location &Other) const {
+ return std::tie(LineNumber, Filename) <
+ std::tie(Other.LineNumber, Other.Filename);
+ }
+
int LineNumber; // Line number of this Location.
SmallString<32> Filename; // File for this Location.
};
diff --git a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
index 7adc1f3d154..7b3e2302ac2 100644
--- a/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MergeTest.cpp
@@ -159,15 +159,37 @@ TEST(MergeTest, mergeFunctionInfos) {
One.IsMethod = true;
One.Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
+ One.Description.emplace_back();
+ auto OneFullComment = &One.Description.back();
+ OneFullComment->Kind = "FullComment";
+ auto OneParagraphComment = llvm::make_unique<CommentInfo>();
+ OneParagraphComment->Kind = "ParagraphComment";
+ auto OneTextComment = llvm::make_unique<CommentInfo>();
+ OneTextComment->Kind = "TextComment";
+ OneTextComment->Text = "This is a text comment.";
+ OneParagraphComment->Children.push_back(std::move(OneTextComment));
+ OneFullComment->Children.push_back(std::move(OneParagraphComment));
+
FunctionInfo Two;
Two.Name = "f";
Two.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
- Two.Loc.emplace_back(20, llvm::SmallString<16>{"test.cpp"});
+ Two.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
Two.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
Two.Params.emplace_back("int", "P");
+ Two.Description.emplace_back();
+ auto TwoFullComment = &Two.Description.back();
+ TwoFullComment->Kind = "FullComment";
+ auto TwoParagraphComment = llvm::make_unique<CommentInfo>();
+ TwoParagraphComment->Kind = "ParagraphComment";
+ auto TwoTextComment = llvm::make_unique<CommentInfo>();
+ TwoTextComment->Kind = "TextComment";
+ TwoTextComment->Text = "This is a text comment.";
+ TwoParagraphComment->Children.push_back(std::move(TwoTextComment));
+ TwoFullComment->Children.push_back(std::move(TwoParagraphComment));
+
std::vector<std::unique_ptr<Info>> Infos;
Infos.emplace_back(llvm::make_unique<FunctionInfo>(std::move(One)));
Infos.emplace_back(llvm::make_unique<FunctionInfo>(std::move(Two)));
@@ -178,13 +200,23 @@ TEST(MergeTest, mergeFunctionInfos) {
Expected->DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
Expected->Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
- Expected->Loc.emplace_back(20, llvm::SmallString<16>{"test.cpp"});
Expected->ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
Expected->Params.emplace_back("int", "P");
Expected->IsMethod = true;
Expected->Parent = Reference(EmptySID, "Parent", InfoType::IT_namespace);
+ Expected->Description.emplace_back();
+ auto ExpectedFullComment = &Expected->Description.back();
+ ExpectedFullComment->Kind = "FullComment";
+ auto ExpectedParagraphComment = llvm::make_unique<CommentInfo>();
+ ExpectedParagraphComment->Kind = "ParagraphComment";
+ auto ExpectedTextComment = llvm::make_unique<CommentInfo>();
+ ExpectedTextComment->Kind = "TextComment";
+ ExpectedTextComment->Text = "This is a text comment.";
+ ExpectedParagraphComment->Children.push_back(std::move(ExpectedTextComment));
+ ExpectedFullComment->Children.push_back(std::move(ExpectedParagraphComment));
+
auto Actual = mergeInfos(Infos);
assert(Actual);
CheckFunctionInfo(InfoAsFunction(Expected.get()),
OpenPOWER on IntegriCloud