diff options
| author | Julie Hockett <juliehockett@google.com> | 2018-08-02 20:10:17 +0000 |
|---|---|---|
| committer | Julie Hockett <juliehockett@google.com> | 2018-08-02 20:10:17 +0000 |
| commit | 8899c29b1e0835f06972b03adab2e8fd91339c8d (patch) | |
| tree | 51f122d564bd08a833ce38a9954852516b40f849 /clang-tools-extra/clang-doc/Representation.cpp | |
| parent | 31da130e4dcce5a4fe72eb187db3e169cba4ec23 (diff) | |
| download | bcm5719-llvm-8899c29b1e0835f06972b03adab2e8fd91339c8d.tar.gz bcm5719-llvm-8899c29b1e0835f06972b03adab2e8fd91339c8d.zip | |
Reland "[clang-doc] Refactoring mapper to map by scope"
Relanding with a minor change to prevent an assertion on release bots.
The result of this adjusted mapper pass is that all Function and Enum
infos are absorbed into the info of their enclosing scope (i.e. the class
or namespace in which they are defined). Namespace and Record infos are
passed along to the final output, but the second pass creates a reference
to each in its parent scope. As a result, the top-level final outputs are
Namespaces and Records.
Differential Revision: https://reviews.llvm.org/D48341
llvm-svn: 338763
Diffstat (limited to 'clang-tools-extra/clang-doc/Representation.cpp')
| -rw-r--r-- | clang-tools-extra/clang-doc/Representation.cpp | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 6107b98ecdc..eacf11a8509 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -26,17 +26,70 @@ namespace clang { namespace doc { -static const SymbolID EmptySID = SymbolID(); +namespace { + +const SymbolID EmptySID = SymbolID(); template <typename T> -std::unique_ptr<Info> reduce(std::vector<std::unique_ptr<Info>> &Values) { - std::unique_ptr<Info> Merged = llvm::make_unique<T>(); +llvm::Expected<std::unique_ptr<Info>> +reduce(std::vector<std::unique_ptr<Info>> &Values) { + if (Values.empty()) + return llvm::make_error<llvm::StringError>(" No values to reduce.\n", + llvm::inconvertibleErrorCode()); + std::unique_ptr<Info> Merged = llvm::make_unique<T>(Values[0]->USR); T *Tmp = static_cast<T *>(Merged.get()); for (auto &I : Values) Tmp->merge(std::move(*static_cast<T *>(I.get()))); - return Merged; + return std::move(Merged); +} + +// Return the index of the matching child in the vector, or -1 if merge is not +// necessary. +template <typename T> +int getChildIndexIfExists(std::vector<T> &Children, T &ChildToMerge) { + for (unsigned long I = 0; I < Children.size(); I++) { + if (ChildToMerge.USR == Children[I].USR) + return I; + } + return -1; +} + +// For References, we don't need to actually merge them, we just don't want +// duplicates. +void reduceChildren(std::vector<Reference> &Children, + std::vector<Reference> &&ChildrenToMerge) { + for (auto &ChildToMerge : ChildrenToMerge) { + if (getChildIndexIfExists(Children, ChildToMerge) == -1) + Children.push_back(std::move(ChildToMerge)); + } +} + +void reduceChildren(std::vector<FunctionInfo> &Children, + std::vector<FunctionInfo> &&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)); + } } +void reduceChildren(std::vector<EnumInfo> &Children, + std::vector<EnumInfo> &&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)); + } +} + +} // namespace + // Dispatch function. llvm::Expected<std::unique_ptr<Info>> mergeInfos(std::vector<std::unique_ptr<Info>> &Values) { @@ -73,7 +126,7 @@ void Info::mergeBase(Info &&Other) { } bool Info::mergeable(const Info &Other) { - return IT == Other.IT && (USR == EmptySID || USR == Other.USR); + return IT == Other.IT && USR == Other.USR; } void SymbolInfo::merge(SymbolInfo &&Other) { @@ -87,6 +140,11 @@ void SymbolInfo::merge(SymbolInfo &&Other) { void NamespaceInfo::merge(NamespaceInfo &&Other) { assert(mergeable(Other)); + // Reduce children if necessary. + reduceChildren(ChildNamespaces, std::move(Other.ChildNamespaces)); + reduceChildren(ChildRecords, std::move(Other.ChildRecords)); + reduceChildren(ChildFunctions, std::move(Other.ChildFunctions)); + reduceChildren(ChildEnums, std::move(Other.ChildEnums)); mergeBase(std::move(Other)); } @@ -100,6 +158,10 @@ void RecordInfo::merge(RecordInfo &&Other) { Parents = std::move(Other.Parents); if (VirtualParents.empty()) VirtualParents = std::move(Other.VirtualParents); + // Reduce children if necessary. + reduceChildren(ChildRecords, std::move(Other.ChildRecords)); + reduceChildren(ChildFunctions, std::move(Other.ChildFunctions)); + reduceChildren(ChildEnums, std::move(Other.ChildEnums)); SymbolInfo::merge(std::move(Other)); } |

