|
|
|||
File indexing completed on 2026-05-10 08:44:37
0001 //===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 #ifndef LLVM_TESTING_SUPPORT_ANNOTATIONS_H 0009 #define LLVM_TESTING_SUPPORT_ANNOTATIONS_H 0010 0011 #include "llvm/ADT/SmallVector.h" 0012 #include "llvm/ADT/StringMap.h" 0013 #include "llvm/ADT/StringRef.h" 0014 #include <tuple> 0015 #include <vector> 0016 0017 namespace llvm { 0018 0019 class raw_ostream; 0020 0021 /// Annotations lets you mark points and ranges inside source code, for tests: 0022 /// 0023 /// Annotations Example(R"cpp( 0024 /// int complete() { x.pri^ } // ^ indicates a point 0025 /// void err() { [["hello" == 42]]; } // [[this is a range]] 0026 /// $definition^class Foo{}; // points can be named: "definition" 0027 /// $(foo)^class Foo{}; // ...or have a payload: "foo" 0028 /// $definition(foo)^class Foo{}; // ...or both 0029 /// $fail(runtime)[[assert(false)]] // ranges can have names/payloads too 0030 /// )cpp"); 0031 /// 0032 /// StringRef Code = Example.code(); // annotations stripped. 0033 /// std::vector<size_t> PP = Example.points(); // all unnamed points 0034 /// size_t P = Example.point(); // there must be exactly one 0035 /// llvm::Range R = Example.range("fail"); // find named ranges 0036 /// 0037 /// Points/ranges are coordinated into `code()` which is stripped of 0038 /// annotations. 0039 /// 0040 /// Names consist of only alphanumeric characters or '_'. 0041 /// Payloads can contain any character expect '(' and ')'. 0042 /// 0043 /// Ranges may be nested (and points can be inside ranges), but there's no way 0044 /// to define general overlapping ranges. 0045 /// 0046 /// FIXME: the choice of the marking syntax makes it impossible to represent 0047 /// some of the C++ and Objective C constructs (including common ones 0048 /// like C++ attributes). We can fix this by: 0049 /// 1. introducing an escaping mechanism for the special characters, 0050 /// 2. making characters for marking points and ranges configurable, 0051 /// 3. changing the syntax to something less commonly used, 0052 /// 4. ... 0053 class Annotations { 0054 public: 0055 /// Two offsets pointing to a continuous substring. End is not included, i.e. 0056 /// represents a half-open range. 0057 struct Range { 0058 size_t Begin = 0; 0059 size_t End = 0; 0060 0061 friend bool operator==(const Range &L, const Range &R) { 0062 return std::tie(L.Begin, L.End) == std::tie(R.Begin, R.End); 0063 } 0064 friend bool operator!=(const Range &L, const Range &R) { return !(L == R); } 0065 }; 0066 0067 /// Parses the annotations from Text. Crashes if it's malformed. 0068 Annotations(llvm::StringRef Text); 0069 0070 /// The input text with all annotations stripped. 0071 /// All points and ranges are relative to this stripped text. 0072 llvm::StringRef code() const { return Code; } 0073 0074 /// Returns the position of the point marked by ^ (or $name^) in the text. 0075 /// Crashes if there isn't exactly one. 0076 size_t point(llvm::StringRef Name = "") const; 0077 /// Returns the position of the point with \p Name and its payload (if any). 0078 std::pair<size_t, llvm::StringRef> 0079 pointWithPayload(llvm::StringRef Name = "") const; 0080 /// Returns the position of all points marked by ^ (or $name^) in the text. 0081 /// Order matches the order within the text. 0082 std::vector<size_t> points(llvm::StringRef Name = "") const; 0083 /// Returns the positions and payloads (if any) of all points named \p Name 0084 std::vector<std::pair<size_t, llvm::StringRef>> 0085 pointsWithPayload(llvm::StringRef Name = "") const; 0086 /// Returns the mapping of all names of points marked in the text to their 0087 /// position. Unnamed points are mapped to the empty string. The positions are 0088 /// sorted. 0089 /// FIXME Remove this and expose `All` directly (currently used out-of-tree) 0090 llvm::StringMap<llvm::SmallVector<size_t, 1>> all_points() const; 0091 0092 /// Returns the location of the range marked by [[ ]] (or $name[[ ]]). 0093 /// Crashes if there isn't exactly one. 0094 Range range(llvm::StringRef Name = "") const; 0095 /// Returns the location and payload of the range marked by [[ ]] 0096 /// (or $name(payload)[[ ]]). Crashes if there isn't exactly one. 0097 std::pair<Range, llvm::StringRef> 0098 rangeWithPayload(llvm::StringRef Name = "") const; 0099 /// Returns the location of all ranges marked by [[ ]] (or $name[[ ]]). 0100 /// They are ordered by start position within the text. 0101 std::vector<Range> ranges(llvm::StringRef Name = "") const; 0102 /// Returns the location of all ranges marked by [[ ]] 0103 /// (or $name(payload)[[ ]]). 0104 /// They are ordered by start position within the text. 0105 std::vector<std::pair<Range, llvm::StringRef>> 0106 rangesWithPayload(llvm::StringRef Name = "") const; 0107 /// Returns the mapping of all names of ranges marked in the text to their 0108 /// location. Unnamed ranges are mapped to the empty string. The ranges are 0109 /// sorted by their start position. 0110 llvm::StringMap<llvm::SmallVector<Range, 1>> all_ranges() const; 0111 0112 private: 0113 std::string Code; 0114 /// Either a Point (Only Start) or a Range (Start and End) 0115 struct Annotation { 0116 size_t Begin; 0117 size_t End = -1; 0118 bool isPoint() const { return End == size_t(-1); } 0119 llvm::StringRef Name; 0120 llvm::StringRef Payload; 0121 }; 0122 std::vector<Annotation> All; 0123 // Values are the indices into All 0124 llvm::StringMap<llvm::SmallVector<size_t, 1>> Points; 0125 llvm::StringMap<llvm::SmallVector<size_t, 1>> Ranges; 0126 }; 0127 0128 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, 0129 const llvm::Annotations::Range &R); 0130 0131 } // namespace llvm 0132 0133 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|