Skip to content

Commit 474bbc1

Browse files
authored
[Support] Enable CRTP for GraphWriter (NFC) (#152322)
Previously, specializing the GraphWriter class required a full class specialization. This change introduces CRTP for GraphWriter, allowing for partial specialization. This change is in support of printing the module dependency graph as part of the RFC for driver-managed module builds, for which we want to print the graph nodes in a more human-readable format by: - Printing descriptive IDs instead of pointer addresses as node labels. - Printing the full node labels separately from the node relations to avoid clutter. With this approach, only GraphWriter::writeNodes() needs to be specialized (, aside from DOTGraphTraits). RFC for driver-managed module builds: https://discourse.llvm.org/t/rfc-modules-support-simple-c-20-modules-use-from-the-clang-driver-without-a-build-system
1 parent e1d6753 commit 474bbc1

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

llvm/include/llvm/Support/GraphWriter.h

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ enum Name {
6161
LLVM_ABI bool DisplayGraph(StringRef Filename, bool wait = true,
6262
GraphProgram::Name program = GraphProgram::DOT);
6363

64-
template<typename GraphType>
65-
class GraphWriter {
64+
template <typename GraphType, typename Derived> class GraphWriterBase {
6665
raw_ostream &O;
6766
const GraphType &G;
6867
bool RenderUsingHTML = false;
@@ -75,9 +74,15 @@ class GraphWriter {
7574
DOTTraits DTraits;
7675

7776
static_assert(std::is_pointer_v<NodeRef>,
78-
"FIXME: Currently GraphWriter requires the NodeRef type to be "
79-
"a pointer.\nThe pointer usage should be moved to "
80-
"DOTGraphTraits, and removed from GraphWriter itself.");
77+
"FIXME: Currently GraphWriterBase requires the NodeRef type to "
78+
"be a pointer.\nThe pointer usage should be moved to "
79+
"DOTGraphTraits, and removed from GraphWriterBase itself.");
80+
81+
// Cast the 'this' pointer to the derived type and return a reference.
82+
Derived &getDerived() { return *static_cast<Derived *>(this); }
83+
const Derived &getDerived() const {
84+
return *static_cast<const Derived *>(this);
85+
}
8186

8287
// Writes the edge labels of the node to O and returns true if there are any
8388
// edge labels not equal to the empty string "".
@@ -118,23 +123,24 @@ class GraphWriter {
118123
}
119124

120125
public:
121-
GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
126+
GraphWriterBase(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
122127
DTraits = DOTTraits(SN);
123128
RenderUsingHTML = DTraits.renderNodesUsingHTML();
124129
}
130+
virtual ~GraphWriterBase() {}
125131

126132
void writeGraph(const std::string &Title = "") {
127133
// Output the header for the graph...
128-
writeHeader(Title);
134+
getDerived().writeHeader(Title);
129135

130136
// Emit all of the nodes in the graph...
131-
writeNodes();
137+
getDerived().writeNodes();
132138

133139
// Output any customizations on the graph
134-
DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, *this);
140+
DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, getDerived());
135141

136142
// Output the end of the graph
137-
writeFooter();
143+
getDerived().writeFooter();
138144
}
139145

140146
void writeHeader(const std::string &Title) {
@@ -166,8 +172,8 @@ class GraphWriter {
166172
void writeNodes() {
167173
// Loop over the graph, printing it out...
168174
for (const auto Node : nodes<GraphType>(G))
169-
if (!isNodeHidden(Node))
170-
writeNode(Node);
175+
if (!getDerived().isNodeHidden(Node))
176+
getDerived().writeNode(Node);
171177
}
172178

173179
bool isNodeHidden(NodeRef Node) { return DTraits.isNodeHidden(Node, G); }
@@ -302,9 +308,9 @@ class GraphWriter {
302308
if (DTraits.getEdgeSourceLabel(Node, EI).empty())
303309
edgeidx = -1;
304310

305-
emitEdge(static_cast<const void*>(Node), edgeidx,
306-
static_cast<const void*>(TargetNode), DestPort,
307-
DTraits.getEdgeAttributes(Node, EI, G));
311+
getDerived().emitEdge(static_cast<const void *>(Node), edgeidx,
312+
static_cast<const void *>(TargetNode), DestPort,
313+
DTraits.getEdgeAttributes(Node, EI, G));
308314
}
309315
}
310316

@@ -357,10 +363,17 @@ class GraphWriter {
357363
}
358364
};
359365

360-
template<typename GraphType>
366+
template <typename GraphType>
367+
class GraphWriter : public GraphWriterBase<GraphType, GraphWriter<GraphType>> {
368+
public:
369+
GraphWriter(raw_ostream &o, const GraphType &g, bool SN)
370+
: GraphWriterBase<GraphType, GraphWriter<GraphType>>(o, g, SN) {}
371+
~GraphWriter() override {}
372+
};
373+
374+
template <typename GraphType>
361375
raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
362-
bool ShortNames = false,
363-
const Twine &Title = "") {
376+
bool ShortNames = false, const Twine &Title = "") {
364377
// Start the graph emission process...
365378
GraphWriter<GraphType> W(O, G, ShortNames);
366379

0 commit comments

Comments
 (0)