22 llvm::errs() <<
"Annotated testcase: " << Msg <<
"\n" << Code <<
"\n";
37 "point and range begin markers cannot be prefixes of each other");
40 "point and range end markers cannot be prefixes of each other");
43 "point and name markers cannot be prefixes of each other");
46 "range begin and range end markers cannot be prefixes of each other");
49 "range begin and name markers cannot be prefixes of each other");
52 "range end and name markers cannot be prefixes of each other");
54 auto Require = [Text](
bool Assertion,
const llvm::Twine &Msg) {
57 std::optional<llvm::StringRef> Name;
58 std::optional<llvm::StringRef> Payload;
62 while (!Text.empty()) {
65 {Code.size(), size_t(-1), Name.value_or(
""), Payload.value_or(
"")});
66 Points[Name.value_or(
"")].push_back(All.size() - 1);
68 Payload = std::nullopt;
73 {Code.size(), size_t(-1), Name.value_or(
""), Payload.value_or(
"")});
75 Payload = std::nullopt;
78 Require(!Name,
Markers.
Name +
"name should be followed by " +
83 const Annotation &NewRange = OpenRanges.
back();
85 {NewRange.Begin, Code.size(), NewRange.Name, NewRange.Payload});
86 Ranges[NewRange.Name].push_back(All.size() - 1);
94 Text = Text.drop_front(Name->size());
96 if (Text.consume_front(
"(")) {
97 Payload = Text.take_while([](
char C) {
return C !=
')'; });
98 Require(Text.size() > Payload->size(),
"unterminated payload");
99 Text = Text.drop_front(Payload->size() + 1);
104 Code.push_back(Text.front());
105 Text = Text.drop_front();
107 Require(!Name,
"unterminated " +
Markers.
Name +
"name");
115std::pair<size_t, llvm::StringRef>
117 auto I = Points.find(Name);
118 require(
I != Points.end() &&
I->getValue().size() == 1,
119 "expected exactly one point", Code);
120 const Annotation &
P = All[
I->getValue()[0]];
121 return {
P.Begin,
P.Payload};
126 std::vector<size_t> Positions;
127 Positions.reserve(Pts.size());
128 for (
const auto &[Point, Payload] : Pts)
129 Positions.push_back(Point);
133std::vector<std::pair<size_t, llvm::StringRef>>
135 auto Iter = Points.find(Name);
136 if (Iter == Points.end())
139 std::vector<std::pair<size_t, llvm::StringRef>> Res;
140 Res.reserve(Iter->getValue().size());
141 for (
size_t I : Iter->getValue())
142 Res.push_back({All[
I].Begin, All[
I].Payload});
149 for (
const auto &Name : Points.keys()) {
151 Result[Name] = {Pts.begin(), Pts.end()};
160std::pair<Annotations::Range, llvm::StringRef>
162 auto I = Ranges.find(Name);
163 require(
I != Ranges.end() &&
I->getValue().size() == 1,
164 "expected exactly one range", Code);
165 const Annotation &R = All[
I->getValue()[0]];
166 return {{R.Begin, R.End}, R.Payload};
169std::vector<Annotations::Range>
172 std::vector<Annotations::Range> Res;
173 Res.reserve(WithPayload.size());
174 for (
const auto &[
Range, Payload] : WithPayload)
175 Res.push_back(
Range);
178std::vector<std::pair<Annotations::Range, llvm::StringRef>>
180 auto Iter = Ranges.find(Name);
181 if (Iter == Ranges.end())
184 std::vector<std::pair<Annotations::Range, llvm::StringRef>> Res;
185 Res.reserve(Iter->getValue().size());
186 for (
size_t I : Iter->getValue())
198 Res[Name] = {R.begin(), R.end()};
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void require(bool Assertion, const llvm::Twine &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 reserve(size_type N)
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",...
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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)
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Markers used to denote points, names/payloads and ranges in the annotated text.
llvm::StringRef RangeBegin
Two offsets pointing to a continuous substring.