This patch contains new features to help when two templated types are within a single diagnostic.<div><br></div><div>New features:</div><div>- Selective highlighting within the type name. Text will be bolded to show the difference within types. For instance, if a pair<bool, int> is used where a pair<double, int>, then the only bool and double will be bold in the diagnostic.</div>
<div>- Type eliding. The common type between two templates leaving only types that important to the structure or differing types. In a pair<bool, int> vs pair<double, int>, the diagnostic will show pair<bool, [...]> vs pair<double, [...]>. Multiple elided types are stacked to reduced space. Controlled by -f(no-)elide-type</div>
<div>- Tree printing. This feature formats the template as a tree with one type per line. This expanded format gives an easier view of the entire structure. Continuing with pair<bool, int> vs pair<double, int>, the output is:</div>
<div> pair<</div><div> [bool != double]</div><div> int ></div><div>This feature is controlled by -f(no-)diagnostics-show-template-tree and also works with type eliding.</div><div><br></div><div>Currently, this feature is only enabled on candidate function notes.</div>
<div><br></div><div>Examples below.</div><div><br></div><div>Given this code:</div><div>template <typename T1, typename T2> class Alpha {};</div><div><div>template <typename T1, typename T2> class Bravo {};</div>
<div>template <typename T1, typename T2> class Charlie {};</div><div>template <typename T1, typename T2> class Delta {};</div><div><br></div><div>void Function1(Alpha<int, void>) {};</div><div>void Function2(Alpha<Bravo<Charlie<Delta<void, void>, Delta<double, Alpha<const int, bool> > >, int>, int>) {};</div>
<div><br></div><div>void foo() {</div><div> Function1(Alpha<int, int>());</div><div> Function2(Alpha<Bravo<Charlie<Delta<void, int>, Delta<double, Alpha<const int, bool> > >, int>, double>());</div>
<div>}</div></div><div><br></div><div>Seeing the error in the Function1 call is easy, but the Function2 is harder.</div><div><div>Currently, clang gives these diagnostics:</div></div><div><br></div><div><div><div>templatediff.cc:10:3: error: no matching function for call to 'Function1'</div>
<div> Function1(Alpha<int, int>());</div><div> ^~~~~~~~~</div><div>templatediff.cc:6:6: note: candidate function not viable: no known conversion</div><div> from 'Alpha<int, int>' to 'Alpha<int, void>' for 1st argument;</div>
<div>void Function1(Alpha<int, void>) {};</div><div> ^</div><div>templatediff.cc:11:3: error: no matching function for call to 'Function2'</div><div> Function2(Alpha<Bravo<Charlie<Delta<void, int>, Delta<double, ...</div>
<div> ^~~~~~~~~</div><div>templatediff.cc:7:6: note: candidate function not viable: no known conversion</div><div> from 'Alpha<Bravo<Charlie<Delta<void, int>, Delta<double, Alpha<const int,</div>
<div> bool> > >, int>, double>' to 'Alpha<Bravo<Charlie<Delta<void, void>,</div><div> Delta<double, Alpha<const int, bool> > >, int>, int>' for 1st argument;</div>
<div>void Function2(Alpha<Bravo<Charlie<Delta<void, void>, Delta<double, ...</div><div> ^</div><div>2 errors generated.</div></div></div><div><br></div><div>Now, with type eliding:</div><div><br></div>
<div><div>templatediff.cc:10:3: error: no matching function for call to 'Function1'</div><div> Function1(Alpha<int, int>());</div><div> ^~~~~~~~~</div><div>templatediff.cc:6:6: note: candidate function not viable: no known conversion</div>
<div> from 'Alpha<[...], int>' to 'Alpha<[...], void>' for 1st argument;</div><div>void Function1(Alpha<int, void>) {};</div><div> ^</div><div>templatediff.cc:11:3: error: no matching function for call to 'Function2'</div>
<div> Function2(Alpha<Bravo<Charlie<Delta<void, int>, Delta<double, ...</div><div> ^~~~~~~~~</div><div>templatediff.cc:7:6: note: candidate function not viable: no known conversion</div><div> from 'Alpha<Bravo<Charlie<Delta<[...], int>, [...]>, [...]>, double>'</div>
<div> to 'Alpha<Bravo<Charlie<Delta<[...], void>, [...]>, [...]>, int>' for</div><div> 1st argument;</div><div>void Function2(Alpha<Bravo<Charlie<Delta<void, void>, Delta<double, ...</div>
<div> ^</div><div>2 errors generated.</div></div><div><br></div><div>Removal of types in common makes the differing types easier to see. Also, they would be bolded if the screen supports it.</div><div><br></div><div>
Once more, with tree printing and no eliding:</div><div><br></div><div><div>templatediff.cc:10:3: error: no matching function for call to 'Function1'</div><div> Function1(Alpha<int, int>());</div><div> ^~~~~~~~~</div>
<div>templatediff.cc:6:6: note: candidate function not viable: no known conversion</div><div> for 1st argument;</div><div> Alpha<</div><div> int</div><div> [void != int] ></div><div>void Function1(Alpha<int, void>) {};</div>
<div> ^</div><div>templatediff.cc:11:3: error: no matching function for call to 'Function2'</div><div> Function2(Alpha<Bravo<Charlie<Delta<void, int>, Delta<double, ...</div><div> ^~~~~~~~~</div>
<div>templatediff.cc:7:6: note: candidate function not viable: no known conversion</div><div> for 1st argument;</div><div> Alpha<</div><div> Bravo<</div><div> Charlie<</div><div> Delta<</div>
<div> void</div><div> [void != int] ></div><div> Delta<</div><div> double</div><div> Alpha<</div><div> const int</div><div> _Bool > > ></div>
<div> int ></div><div> [int != double] ></div><div>void Function2(Alpha<Bravo<Charlie<Delta<void, void>, Delta<double, ...</div><div> ^</div><div>2 errors generated.</div></div><div><br>
</div><div>This takes more lines, but gives a detailed look at the templates.</div><div><br></div><div>I have attached a patch and also made it available at <a href="http://codereview.appspot.com/5487054/">http://codereview.appspot.com/5487054/</a> Questions and comments welcome.</div>
<div><br></div>