This is an archive of the discontinued LLVM Phabricator instance.

[llvm][ADT] Overload output stream operator `<<` for `StringMapEntry` and `StringMap`.
ClosedPublic

Authored by wyt on Aug 26 2022, 9:04 AM.

Details

Summary

Printing support enables the production of more useful error messages in unit testing e.g. when using matchers such as UnorderedElementsAre() to inspect the contents of a StringMap.

Diff Detail

Unit TestsFailed

Event Timeline

wyt created this revision.Aug 26 2022, 9:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 26 2022, 9:04 AM
Herald added a subscriber: mgrang. · View Herald Transcript
wyt requested review of this revision.Aug 26 2022, 9:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 26 2022, 9:04 AM
wyt updated this revision to Diff 455963.Aug 26 2022, 11:19 AM

Check if << operator is overloaded for value type, return a default if << is unimplemented.

Please clarify in the CL description that the more useful error messages will appear in unit test failures, for example when UnorderedElementsAre() is used with StringMap.

llvm/include/llvm/ADT/StringMap.h
502 ↗(On Diff #455963)
llvm/include/llvm/ADT/StringMapEntry.h
150 ↗(On Diff #455963)

WDYT about "CanOutputToOstream"?

150 ↗(On Diff #455963)

Similar to hiding implementation details in DenseMap.h and in other headers, I'd suggest to put this type trait inside namespace detail {}.

163 ↗(On Diff #455963)
166 ↗(On Diff #455963)

I wonder if we should put these operators into llvm/Testing/ADT, since these operators are only supposed to be used from tests. For production code, LLVM strongly prefers llvm::raw_ostream, a much more light-weight type than std::ostream.

In fact, this is the first operator<<(std::ostream&, <anything>) overload in llvm/ADT. Printable types (like APInt) are printable into raw_ostream.

Another option is to provide operator<<(llvm::raw_ostream&) in llvm/ADT, and wrap them in operator<<(std::ostream&) in llvm/Testing/ADT. The llvm/ADT version won't have the SFINAE magic, but the llvm/Testing/ADT one will.

WDYT?

wyt updated this revision to Diff 456313.Aug 29 2022, 5:08 AM
wyt marked 5 inline comments as done.

Address comments.

wyt added inline comments.Aug 29 2022, 5:08 AM
llvm/include/llvm/ADT/StringMapEntry.h
166 ↗(On Diff #455963)

Moved the printing into Testing/ADT.

I also attempted the second approach but it wasn't very successful. Using <<(llvm::raw_ostream) from <<(std::ostream) meant that <<(llvm::raw_ostream) needed to be implemented for any structure we wanted to print. However for use cases related to google test, it is more likely that users implement the <<(std::ostream) operator and not the <<(llvm::raw_ostream).

wyt edited the summary of this revision. (Show Details)Aug 29 2022, 5:29 AM
gribozavr2 added inline comments.Aug 29 2022, 5:34 AM
llvm/include/llvm/ADT/StringMapEntry.h
166 ↗(On Diff #455963)

Using <<(llvm::raw_ostream) from <<(std::ostream) meant that <<(llvm::raw_ostream) needed to be implemented

What I meant is that when implementing <<(std::ostream) you can call <<(llvm::raw_ostream) printing into a string, and then print the string into the std::ostream.

But that's not necessary, what you have now also works.

wyt updated this revision to Diff 456640.Aug 30 2022, 6:01 AM

Rename build target.

gribozavr2 accepted this revision.Aug 30 2022, 6:07 AM
This revision is now accepted and ready to land.Aug 30 2022, 6:07 AM
wyt added a reviewer: ymandel.Aug 30 2022, 8:43 AM
sgatev accepted this revision.Aug 30 2022, 8:56 AM
ymandel accepted this revision.Aug 30 2022, 8:57 AM
ymandel added inline comments.
llvm/include/llvm/Testing/ADT/StringMap.h
27

Is there a standard representation for empty maps and, if so, is this it?

wyt added inline comments.Aug 30 2022, 9:33 AM
llvm/include/llvm/Testing/ADT/StringMap.h
27

I'm not aware of one, imo { } seemed pretty representative of maps.
Do you have a preference?

wyt updated this revision to Diff 456928.Aug 31 2022, 4:53 AM

Minor fixes:

  • Update sfinea to check on ostream& and use decltype to get type of the input to be streamed
  • Fix build target dependency
gribozavr2 accepted this revision.Aug 31 2022, 4:59 AM
This revision was landed with ongoing or failed builds.Aug 31 2022, 10:39 AM
This revision was automatically updated to reflect the committed changes.
dblaikie added inline comments.Sep 8 2022, 2:50 PM
llvm/include/llvm/Testing/ADT/StringMap.h
27

do we need the special case for empty, or can it flow out of the general case naturally?

wyt added inline comments.Sep 9 2022, 2:35 AM
llvm/include/llvm/Testing/ADT/StringMap.h
27

The special case keeps the braces on the same line for readability, otherwise they would be on separate lines.