xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/OutputAggregator.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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