//===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_TESTING_SUPPORT_ANNOTATIONS_H #define LLVM_TESTING_SUPPORT_ANNOTATIONS_H #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include <tuple> #include <vector> namespace llvm { class raw_ostream; /// Annotations lets you mark points and ranges inside source code, for tests: /// /// Annotations Example(R"cpp( /// int complete() { x.pri^ } // ^ indicates a point /// void err() { [["hello" == 42]]; } // [[this is a range]] /// $definition^class Foo{}; // points can be named: "definition" /// $(foo)^class Foo{}; // ...or have a payload: "foo" /// $definition(foo)^class Foo{}; // ...or both /// $fail(runtime)[[assert(false)]] // ranges can have names/payloads too /// )cpp"); /// /// StringRef Code = Example.code(); // annotations stripped. /// std::vector<size_t> PP = Example.points(); // all unnamed points /// size_t P = Example.point(); // there must be exactly one /// llvm::Range R = Example.range("fail"); // find named ranges /// /// Points/ranges are coordinated into `code()` which is stripped of /// annotations. /// /// Names consist of only alphanumeric characters or '_'. /// Payloads can contain any character expect '(' and ')'. /// /// Ranges may be nested (and points can be inside ranges), but there's no way /// to define general overlapping ranges. /// /// FIXME: the choice of the marking syntax makes it impossible to represent /// some of the C++ and Objective C constructs (including common ones /// like C++ attributes). We can fix this by: /// 1. introducing an escaping mechanism for the special characters, /// 2. making characters for marking points and ranges configurable, /// 3. changing the syntax to something less commonly used, /// 4. ... class Annotations { … }; llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const llvm::Annotations::Range &R); } // namespace llvm #endif