1 //===- DwarfTransformer.h ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H 10 #define LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H 11 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/DebugInfo/GSYM/ExtractRanges.h" 14 15 #include <map> 16 #include <string> 17 18 namespace llvm { 19 20 class raw_ostream; 21 22 namespace gsym { 23 24 class OutputAggregator { 25 protected: 26 // A std::map is preferable over an llvm::StringMap for presenting results 27 // in a predictable order. 28 std::map<std::string, unsigned> Aggregation; 29 raw_ostream *Out; 30 31 public: OutputAggregator(raw_ostream * out)32 OutputAggregator(raw_ostream *out) : Out(out) {} 33 GetNumCategories()34 size_t GetNumCategories() const { return Aggregation.size(); } 35 Report(StringRef s,std::function<void (raw_ostream & o)> detailCallback)36 void Report(StringRef s, std::function<void(raw_ostream &o)> detailCallback) { 37 Aggregation[std::string(s)]++; 38 if (GetOS()) 39 detailCallback(*Out); 40 } 41 EnumerateResults(std::function<void (StringRef,unsigned)> handleCounts)42 void EnumerateResults( 43 std::function<void(StringRef, unsigned)> handleCounts) const { 44 for (auto &&[name, count] : Aggregation) 45 handleCounts(name, count); 46 } 47 GetOS()48 raw_ostream *GetOS() const { return Out; } 49 50 // You can just use the stream, and if it's null, nothing happens. 51 // Don't do a lot of stuff like this, but it's convenient for silly stuff. 52 // It doesn't work with things that have custom insertion operators, though. 53 template <typename T> OutputAggregator &operator<<(T &&value) { 54 if (Out != nullptr) 55 *Out << value; 56 return *this; 57 } 58 59 // For multi-threaded usage, we can collect stuff in another aggregator, 60 // then merge it in here. Note that this is *not* thread safe. It is up to 61 // the caller to ensure that this is only called from one thread at a time. Merge(const OutputAggregator & other)62 void Merge(const OutputAggregator &other) { 63 for (auto &&[name, count] : other.Aggregation) { 64 auto [it, inserted] = Aggregation.emplace(name, count); 65 if (!inserted) 66 it->second += count; 67 } 68 } 69 }; 70 71 } // namespace gsym 72 } // namespace llvm 73 74 #endif // LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H 75