diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-pdbutil/DiffPrinter.h')
-rw-r--r-- | contrib/llvm/tools/llvm-pdbutil/DiffPrinter.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/contrib/llvm/tools/llvm-pdbutil/DiffPrinter.h b/contrib/llvm/tools/llvm-pdbutil/DiffPrinter.h new file mode 100644 index 0000000..475747d --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbutil/DiffPrinter.h @@ -0,0 +1,172 @@ +//===- DiffPrinter.h ------------------------------------------ *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMPDBDUMP_DIFFPRINTER_H +#define LLVM_TOOLS_LLVMPDBDUMP_DIFFPRINTER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" + +#include <list> +#include <unordered_set> + +namespace std { +template <> struct hash<llvm::pdb::PdbRaw_FeatureSig> { + typedef llvm::pdb::PdbRaw_FeatureSig argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type Item) const { + return std::hash<uint32_t>{}(uint32_t(Item)); + } +}; +} // namespace std + +namespace llvm { +namespace pdb { + +class PDBFile; + +enum class DiffResult { UNSPECIFIED, IDENTICAL, EQUIVALENT, DIFFERENT }; + +struct IdenticalDiffProvider { + template <typename T, typename U> + DiffResult compare(const T &Left, const U &Right) { + return (Left == Right) ? DiffResult::IDENTICAL : DiffResult::DIFFERENT; + } + + template <typename T> std::string format(const T &Item, bool Right) { + return formatv("{0}", Item).str(); + } +}; + +struct EquivalentDiffProvider { + template <typename T, typename U> + DiffResult compare(const T &Left, const U &Right) { + return (Left == Right) ? DiffResult::IDENTICAL : DiffResult::EQUIVALENT; + } + + template <typename T> std::string format(const T &Item, bool Right) { + return formatv("{0}", Item).str(); + } +}; + +class DiffPrinter { +public: + DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth, + uint32_t FieldWidth, bool Result, bool Values, + raw_ostream &Stream); + ~DiffPrinter(); + + template <typename T, typename U> struct Identical {}; + + template <typename Provider = IdenticalDiffProvider, typename T, typename U> + void print(StringRef Property, const T &Left, const U &Right, + Provider P = Provider()) { + std::string L = P.format(Left, false); + std::string R = P.format(Right, true); + + DiffResult Result = P.compare(Left, Right); + printExplicit(Property, Result, L, R); + } + + void printExplicit(StringRef Property, DiffResult C, StringRef Left, + StringRef Right); + + template <typename T, typename U> + void printExplicit(StringRef Property, DiffResult C, const T &Left, + const U &Right) { + std::string L = formatv("{0}", Left).str(); + std::string R = formatv("{0}", Right).str(); + printExplicit(Property, C, StringRef(L), StringRef(R)); + } + + template <typename T, typename U> + void diffUnorderedArray(StringRef Property, ArrayRef<T> Left, + ArrayRef<U> Right) { + std::unordered_set<T> LS(Left.begin(), Left.end()); + std::unordered_set<U> RS(Right.begin(), Right.end()); + std::string Count1 = formatv("{0} element(s)", Left.size()); + std::string Count2 = formatv("{0} element(s)", Right.size()); + print(std::string(Property) + "s (set)", Count1, Count2); + for (const auto &L : LS) { + auto Iter = RS.find(L); + std::string Text = formatv("{0}", L).str(); + if (Iter == RS.end()) { + print(Property, Text, "(not present)"); + continue; + } + print(Property, Text, Text); + RS.erase(Iter); + } + for (const auto &R : RS) { + auto Iter = LS.find(R); + std::string Text = formatv("{0}", R).str(); + if (Iter == LS.end()) { + print(Property, "(not present)", Text); + continue; + } + print(Property, Text, Text); + } + } + + template <typename ValueProvider = IdenticalDiffProvider, typename T, + typename U> + void diffUnorderedMap(StringRef Property, const StringMap<T> &Left, + const StringMap<U> &Right, + ValueProvider P = ValueProvider()) { + StringMap<U> RightCopy(Right); + + std::string Count1 = formatv("{0} element(s)", Left.size()); + std::string Count2 = formatv("{0} element(s)", Right.size()); + print(std::string(Property) + "s (map)", Count1, Count2); + + for (const auto &L : Left) { + auto Iter = RightCopy.find(L.getKey()); + if (Iter == RightCopy.end()) { + printExplicit(L.getKey(), DiffResult::DIFFERENT, L.getValue(), + "(not present)"); + continue; + } + + print(L.getKey(), L.getValue(), Iter->getValue(), P); + RightCopy.erase(Iter); + } + + for (const auto &R : RightCopy) { + printExplicit(R.getKey(), DiffResult::DIFFERENT, "(not present)", + R.getValue()); + } + } + + void printFullRow(StringRef Text); + +private: + uint32_t tableWidth() const; + + void printHeaderRow(); + void printSeparatorRow(); + void newLine(char InitialChar = '|'); + void printValue(StringRef Value, DiffResult C, AlignStyle Style, + uint32_t Width, bool Force); + void printResult(DiffResult Result); + + bool PrintResult; + bool PrintValues; + uint32_t Indent; + uint32_t PropertyWidth; + uint32_t FieldWidth; + raw_ostream &OS; +}; +} // namespace pdb +} // namespace llvm + +#endif |