21 llvm::errs() <<
"Annotated testcase: " << Msg <<
"\n" << Code <<
"\n";
27 auto Require = [Text](
bool Assertion,
const char *Msg) {
30 std::optional<llvm::StringRef>
Name;
31 std::optional<llvm::StringRef> Payload;
34 Code.reserve(Text.size());
35 while (!Text.empty()) {
36 if (Text.consume_front(
"^")) {
38 {Code.size(),
size_t(-1),
Name.value_or(
""), Payload.value_or(
"")});
39 Points[
Name.value_or(
"")].push_back(All.size() - 1);
41 Payload = std::nullopt;
44 if (Text.consume_front(
"[[")) {
46 {Code.size(),
size_t(-1),
Name.value_or(
""), Payload.value_or(
"")});
48 Payload = std::nullopt;
51 Require(!
Name,
"$name should be followed by ^ or [[");
52 if (Text.consume_front(
"]]")) {
53 Require(!OpenRanges.
empty(),
"unmatched ]]");
55 const Annotation &NewRange = OpenRanges.
back();
57 {NewRange.Begin, Code.size(), NewRange.Name, NewRange.Payload});
58 Ranges[NewRange.Name].push_back(All.size() - 1);
63 if (Text.consume_front(
"$")) {
65 Text.take_while([](
char C) {
return llvm::isAlnum(
C) ||
C ==
'_'; });
66 Text = Text.drop_front(
Name->size());
68 if (Text.consume_front(
"(")) {
69 Payload = Text.take_while([](
char C) {
return C !=
')'; });
70 Require(Text.size() > Payload->size(),
"unterminated payload");
71 Text = Text.drop_front(Payload->size() + 1);
76 Code.push_back(Text.front());
77 Text = Text.drop_front();
79 Require(!
Name,
"unterminated $name");
80 Require(OpenRanges.
empty(),
"unmatched [[");
87std::pair<size_t, llvm::StringRef>
91 "expected exactly one point", Code);
92 const Annotation &
P = All[
I->getValue()[0]];
93 return {
P.Begin,
P.Payload};
98 std::vector<size_t> Positions;
99 Positions.reserve(Pts.size());
100 for (
const auto &[Point, Payload] : Pts)
101 Positions.push_back(Point);
105std::vector<std::pair<size_t, llvm::StringRef>>
108 if (Iter == Points.
end())
111 std::vector<std::pair<size_t, llvm::StringRef>> Res;
112 Res.reserve(Iter->getValue().size());
113 for (
size_t I : Iter->getValue())
114 Res.push_back({All[
I].Begin, All[
I].Payload});
121 for (
const auto &
Name : Points.
keys()) {
123 Result[
Name] = {Pts.begin(), Pts.end()};
132std::pair<Annotations::Range, llvm::StringRef>
136 "expected exactly one range", Code);
137 const Annotation &R = All[
I->getValue()[0]];
138 return {{R.Begin, R.End}, R.Payload};
141std::vector<Annotations::Range>
144 std::vector<Annotations::Range> Res;
145 Res.reserve(WithPayload.size());
146 for (
const auto &[
Range, Payload] : WithPayload)
147 Res.push_back(
Range);
150std::vector<std::pair<Annotations::Range, llvm::StringRef>>
153 if (Iter == Ranges.
end())
156 std::vector<std::pair<Annotations::Range, llvm::StringRef>> Res;
157 Res.reserve(Iter->getValue().size());
158 for (
size_t I : Iter->getValue())
170 Res[
Name] = {R.begin(), R.end()};
static void require(bool Assertion, const char *Msg, llvm::StringRef Code)
Annotations(llvm::StringRef Text)
Parses the annotations from Text. Crashes if it's malformed.
std::vector< std::pair< size_t, llvm::StringRef > > pointsWithPayload(llvm::StringRef Name="") const
Returns the positions and payloads (if any) of all points named Name.
Range range(llvm::StringRef Name="") const
Returns the location of the range marked by [[ ]] (or $name[[ ]]).
size_t point(llvm::StringRef Name="") const
Returns the position of the point marked by ^ (or $name^) in the text.
std::pair< size_t, llvm::StringRef > pointWithPayload(llvm::StringRef Name="") const
Returns the position of the point with Name and its payload (if any).
llvm::StringMap< llvm::SmallVector< size_t, 1 > > all_points() const
Returns the mapping of all names of points marked in the text to their position.
std::pair< Range, llvm::StringRef > rangeWithPayload(llvm::StringRef Name="") const
Returns the location and payload of the range marked by [[ ]] (or $name(payload)[[ ]]).
std::vector< Range > ranges(llvm::StringRef Name="") const
Returns the location of all ranges marked by [[ ]] (or $name[[ ]]).
std::vector< std::pair< Range, llvm::StringRef > > rangesWithPayload(llvm::StringRef Name="") const
Returns the location of all ranges marked by [[ ]] (or $name(payload)[[ ]]).
llvm::StringMap< llvm::SmallVector< Range, 1 > > all_ranges() const
Returns the mapping of all names of ranges marked in the text to their location.
std::vector< size_t > points(llvm::StringRef Name="") const
Returns the position of all points marked by ^ (or $name^) in the text.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
iterator_range< StringMapKeyIterator< ValueTy > > keys() const
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Two offsets pointing to a continuous substring.