This is an archive of the discontinued LLVM Phabricator instance.

[Support] Provide access to the full mapping in llvm::Annotations
ClosedPublic

Authored by li.zhe.hua on Sep 16 2022, 1:13 PM.

Details

Summary

Providing access to the mapping of annotations allows test helpers to
be expressive by using the annotations as expectations. For example, a
matcher could verify that all annotated points were matched by a
matcher, or that an refactoring surgically modifies specific ranges.

Diff Detail

Event Timeline

li.zhe.hua created this revision.Sep 16 2022, 1:13 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 16 2022, 1:13 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
li.zhe.hua requested review of this revision.Sep 16 2022, 1:13 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 16 2022, 1:13 PM
ymandel accepted this revision.Sep 19 2022, 11:57 AM
ymandel added a subscriber: ymandel.
ymandel added inline comments.
llvm/include/llvm/Testing/Support/Annotations.h
76
llvm/unittests/Support/AnnotationsTest.cpp
21–24

Use using decls for these?

93

why ElementsAre vs UnorderedElementsAre?

This revision is now accepted and ready to land.Sep 19 2022, 11:57 AM
li.zhe.hua marked 3 inline comments as done.

Address comments

llvm/unittests/Support/AnnotationsTest.cpp
93

I've added a sentence to the documentation, clarifying the ordering.

gribozavr2 accepted this revision.Sep 19 2022, 3:05 PM
gribozavr2 added inline comments.
llvm/include/llvm/Testing/Support/Annotations.h
77

"The positions are sorted." ?

88

"The ranges are sorted by their start position." ?

This revision was landed with ongoing or failed builds.Sep 20 2022, 8:08 AM
This revision was automatically updated to reflect the committed changes.

It would be great to understand a bit more about how/where this is used. (It looks like out-of-tree, but I can't find the actual testcases in question).

using the annotations as expectations

This was something deliberately left out of the original design. Names for lookup vs payload metadata on the points are IMO better expressed as separate concerns. The former was much more pressing and we had less experience with the latter so left it out. We're currently coming back to it in D137909, a syntax like $foo(bar) will be used to attach data bar to a point named foo.

For these methods (which I just learned about in reviewing that patch), we could do some combination of:

  • leave them exactly as-is (payloads not exposed)
  • adapt them mechanically to the data model with payloads
  • remove them and then redesign something for the use case using payloads (e.g. if they're not really used and payload is a better fit for the planned usecase)

So the two functions I added were because previously using Annotations required knowledge of the annotation names a priori. If you are constructing one and using it directly yourself in a test, great. If you handed the Annotations object to a helper function, you'd also need to hand the two sets of names with it (one for points and one for ranges), otherwise the helper function doesn't know what annotations exist. In our case, the helper function is a googletest matcher verifying matches on AST nodes are bound to IDs matching the annotations listed. However, if no nodes are matched, we can't verify that all annotated nodes were matched without a lot of extra (possibly error-prone) boilerplate.

Ultimately, we only really need the names. Returning the full map was mostly for simplicity (if you want all the names, you probably will query all the values eventually), but really the key (... heh) piece of data we need is the names from the maps.

Yes, this makes sense. I think exposing just the names is a bit "clever".

If we changed the internal structure to be an array of struct {

StringRef Name;
StringRef Payload;
size_t Start;
size_t End; // -1 for a point

}
Then how do you feel if we expose that array and drop the current maps?

Yeah, that seems like it'd work just fine for us.