LLVM 23.0.0git
Annotations.h
Go to the documentation of this file.
1//===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8#ifndef LLVM_TESTING_SUPPORT_ANNOTATIONS_H
9#define LLVM_TESTING_SUPPORT_ANNOTATIONS_H
10
12#include "llvm/ADT/StringMap.h"
13#include "llvm/ADT/StringRef.h"
14#include <tuple>
15#include <vector>
16
17namespace llvm {
18
19class raw_ostream;
20
21/// Annotations lets you mark points and ranges inside source code, for tests:
22///
23/// Annotations Example(R"cpp(
24/// int complete() { x.pri^ } // ^ indicates a point
25/// void err() { [["hello" == 42]]; } // [[this is a range]]
26/// $definition^class Foo{}; // points can be named: "definition"
27/// $(foo)^class Foo{}; // ...or have a payload: "foo"
28/// $definition(foo)^class Foo{}; // ...or both
29/// $fail(runtime)[[assert(false)]] // ranges can have names/payloads
30/// // too
31/// )cpp");
32///
33/// StringRef Code = Example.code(); // annotations stripped.
34/// std::vector<size_t> PP = Example.points(); // all unnamed points
35/// size_t P = Example.point(); // there must be exactly one
36/// llvm::Range R = Example.range("fail"); // find named ranges
37///
38/// Points/ranges are coordinated into `code()` which is stripped of
39/// annotations.
40///
41/// Names consist of only alphanumeric characters or '_'.
42/// Payloads can contain any character expect '(' and ')'.
43///
44/// Ranges may be nested (and points can be inside ranges), but there's no way
45/// to define general overlapping ranges.
46///
47/// The markers for points, names and ranges can be customized. This is useful
48/// when the default markers would otherwise conflict with the underlying syntax
49/// (e.g. C++ attributes or the reflection operator). For example, to use "~" as
50/// the point marker, "@@" as the name/payload marker, and "{{" / "}}" as range
51/// delimiters:
52///
53/// Annotations Example("~point @@name{{range}}", {"~", "@@", "{{", "}}"});
54///
55/// Alternatively, use setters to customize markers individually:
56///
57/// // Customize only the point marker, leaving the rest as default:
58/// Annotations Example("~point $name[[range]]", Annotations::Markers()
59/// .setPoint("~"));
60///
61/// // Customize all markers:
62/// Annotations Example("~point @@name{{range}}", Annotations::Markers()
63/// .setPoint("~")
64/// .setName("@@")
65/// .setRangeBegin("{{")
66/// .setRangeEnd("}}"));
68public:
69 /// Two offsets pointing to a continuous substring. End is not included, i.e.
70 /// represents a half-open range.
71 struct Range {
72 size_t Begin = 0;
73 size_t End = 0;
74
75 friend bool operator==(const Range &L, const Range &R) {
76 return std::tie(L.Begin, L.End) == std::tie(R.Begin, R.End);
77 }
78 friend bool operator!=(const Range &L, const Range &R) { return !(L == R); }
79 };
80
81 /// Markers used to denote points, names/payloads and ranges in the annotated
82 /// text.
83 struct Markers {
88
90 Point = P;
91 return *this;
92 }
94 Name = N;
95 return *this;
96 }
98 RangeBegin = B;
99 return *this;
100 }
102 RangeEnd = E;
103 return *this;
104 }
105 };
106
107 /// Parses the annotations from Text. Crashes if it's malformed.
109 /// Parses the annotations from Text using custom markers.
110 /// Markers must be non-empty and unambiguous.
112
113 /// The input text with all annotations stripped.
114 /// All points and ranges are relative to this stripped text.
115 llvm::StringRef code() const { return Code; }
116
117 /// Returns the position of the point marked by ^ (or $name^) in the text.
118 /// Crashes if there isn't exactly one.
119 size_t point(llvm::StringRef Name = "") const;
120 /// Returns the position of the point with \p Name and its payload (if any).
121 std::pair<size_t, llvm::StringRef>
122 pointWithPayload(llvm::StringRef Name = "") const;
123 /// Returns the position of all points marked by ^ (or $name^) in the text.
124 /// Order matches the order within the text.
125 std::vector<size_t> points(llvm::StringRef Name = "") const;
126 /// Returns the positions and payloads (if any) of all points named \p Name
127 std::vector<std::pair<size_t, llvm::StringRef>>
128 pointsWithPayload(llvm::StringRef Name = "") const;
129 /// Returns the mapping of all names of points marked in the text to their
130 /// position. Unnamed points are mapped to the empty string. The positions are
131 /// sorted.
132 /// FIXME Remove this and expose `All` directly (currently used out-of-tree)
134
135 /// Returns the location of the range marked by [[ ]] (or $name[[ ]]).
136 /// Crashes if there isn't exactly one.
137 Range range(llvm::StringRef Name = "") const;
138 /// Returns the location and payload of the range marked by [[ ]]
139 /// (or $name(payload)[[ ]]). Crashes if there isn't exactly one.
140 std::pair<Range, llvm::StringRef>
141 rangeWithPayload(llvm::StringRef Name = "") const;
142 /// Returns the location of all ranges marked by [[ ]] (or $name[[ ]]).
143 /// They are ordered by start position within the text.
144 std::vector<Range> ranges(llvm::StringRef Name = "") const;
145 /// Returns the location of all ranges marked by [[ ]]
146 /// (or $name(payload)[[ ]]).
147 /// They are ordered by start position within the text.
148 std::vector<std::pair<Range, llvm::StringRef>>
149 rangesWithPayload(llvm::StringRef Name = "") const;
150 /// Returns the mapping of all names of ranges marked in the text to their
151 /// location. Unnamed ranges are mapped to the empty string. The ranges are
152 /// sorted by their start position.
154
155private:
156 std::string Code;
157 /// Either a Point (Only Start) or a Range (Start and End)
158 struct Annotation {
159 size_t Begin;
160 size_t End = -1;
161 bool isPoint() const { return End == size_t(-1); }
162 llvm::StringRef Name;
163 llvm::StringRef Payload;
164 };
165 std::vector<Annotation> All;
166 // Values are the indices into All
167 llvm::StringMap<llvm::SmallVector<size_t, 1>> Points;
168 llvm::StringMap<llvm::SmallVector<size_t, 1>> Ranges;
169};
170
172 const llvm::Annotations::Range &R);
173
174} // namespace llvm
175
176#endif
This file defines the StringMap class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
R600 Emit Clause Markers
This file defines the SmallVector class.
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.
llvm::StringRef code() const
The input text with all annotations stripped.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
#define N
Markers used to denote points, names/payloads and ranges in the annotated text.
Definition Annotations.h:83
Markers & setPoint(llvm::StringRef P)
Definition Annotations.h:89
llvm::StringRef RangeEnd
Definition Annotations.h:87
Markers & setName(llvm::StringRef N)
Definition Annotations.h:93
Markers & setRangeEnd(llvm::StringRef E)
llvm::StringRef RangeBegin
Definition Annotations.h:86
Markers & setRangeBegin(llvm::StringRef B)
Definition Annotations.h:97
Two offsets pointing to a continuous substring.
Definition Annotations.h:71
friend bool operator==(const Range &L, const Range &R)
Definition Annotations.h:75
friend bool operator!=(const Range &L, const Range &R)
Definition Annotations.h:78