LLVM 24.0.0git
SourceMgrDiagnosticVerifier.h
Go to the documentation of this file.
1//===- SourceMgrDiagnosticVerifier.h ---------------------------*- 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//
9// This file defines a utility for verifying that diagnostics reported through
10// a SourceMgr match 'expected-<kind>' comments in the source, for
11// implementing '-verify'-style diagnostic tests on top of a plain
12// llvm::SourceMgr.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_SUPPORT_SOURCEMGRDIAGNOSTICVERIFIER_H
17#define LLVM_SUPPORT_SOURCEMGRDIAGNOSTICVERIFIER_H
18
19#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/StringMap.h"
23#include "llvm/Support/Regex.h"
25#include <optional>
26
27namespace llvm {
28
29class MemoryBuffer;
30class raw_ostream;
31
32/// Scans SourceMgr source buffers for 'expected-<kind>' comments (e.g.
33/// 'expected-error {{message}}') and verifies that the diagnostics reported
34/// to it via \c process match them, and that every expected diagnostic is
35/// matched at least once.
37public:
38 /// The result of matching a single actual diagnostic against the expected
39 /// diagnostics recorded for its location.
40 enum class MatchResult {
41 /// The diagnostic matched an expected diagnostic (kind and text).
43 /// The diagnostic's text matched an expected diagnostic, but its kind
44 /// didn't; a message about this has already been printed.
46 /// The diagnostic did not match any expected diagnostic. The caller is
47 /// responsible for reporting it, if desired.
49 /// The diagnostic did not match, but \p reportUnexpected was false, so
50 /// nothing was printed and nothing needs to be done.
52 };
53
54 /// A single diagnostic expected via an 'expected-<kind>' comment.
55 struct ExpectedDiag {
59
60 /// Returns true if this diagnostic matches the given message.
61 LLVM_ABI bool match(StringRef str) const;
62
63 /// Computes the regex matcher for a '-re' diagnostic's substring.
64 /// Returns false and prints a message through \p mgr on error.
65 LLVM_ABI bool computeRegex(raw_ostream &os, SourceMgr &mgr);
66
67 /// Prints \p msg at this diagnostic's location and returns false, for
68 /// use as `return emitError(...);` in functions that report failure via
69 /// a bool return.
70 LLVM_ABI bool emitError(raw_ostream &os, SourceMgr &mgr,
71 const Twine &msg) const;
72
73 /// The severity of the diagnostic expected.
75 /// The line number the expected diagnostic should be on.
76 unsigned lineNo;
77 /// The column the expected diagnostic should be at, or 0 if any column
78 /// matches.
79 unsigned colNo = 0;
80 /// The location of the expected diagnostic within the input file.
82 /// A flag indicating if the expected diagnostic has been matched yet.
83 bool matched = false;
84 /// The substring that is expected to be within the diagnostic.
86 /// An optional regex matcher, if the expected diagnostic substring was a
87 /// regex string.
88 std::optional<Regex> substringRegex;
89 };
90
91 /// Recognizes directives starting with any of \p prefixes (e.g.
92 /// 'expected-error').
94 "expected"});
95
99
100 /// Given a diagnostic kind, return a human readable string for it.
102
103 /// Prints an error to \p os without going through \p mgr's diagnostic
104 /// handler, which may be the one feeding the verifier.
105 static void printMessage(raw_ostream &os, const SourceMgr &mgr, SMLoc loc,
106 const Twine &msg, ArrayRef<SMRange> ranges = {});
107
108 /// Computes and caches the list of expected diagnostics for \p buf, if not
109 /// already cached. Returns the (mutable) cached list.
110 MutableArrayRef<ExpectedDiag> computeExpectedDiags(raw_ostream &os,
111 SourceMgr &mgr,
112 const MemoryBuffer *buf);
113
114 /// Returns the cached expected diagnostics for the buffer named \p bufName,
115 /// or std::nullopt if \p computeExpectedDiags hasn't been called for it.
116 std::optional<MutableArrayRef<ExpectedDiag>>
117 getExpectedDiags(StringRef bufName);
118
119 /// Returns the expected diagnostics with an '@unknown' location.
121 return expectedUnknownLocDiags;
122 }
123
124 /// Matches a single actual diagnostic against the expected diagnostics
125 /// recorded for \p buf / \p lineNo / \p colNo (1-based), computing them
126 /// first via \p computeExpectedDiags if they haven't been already. If \p
127 /// hasLoc is false, the diagnostic has no location and is matched against
128 /// the '@unknown' list instead (\p buf / \p lineNo / \p colNo are
129 /// ignored). If \p hasLoc is true but \p buf is null (e.g. the
130 /// diagnostic's file isn't a known buffer), the diagnostic is matched
131 /// against an empty list, i.e. it can never match and is always unexpected.
132 /// On a near miss, prints a message through \p mgr. \p reportUnexpected
133 /// controls whether near misses / unexpected diagnostics are reported at
134 /// all.
135 MatchResult process(raw_ostream &os, SourceMgr &mgr, SourceMgr::DiagKind kind,
136 bool hasLoc, const MemoryBuffer *buf, unsigned lineNo,
137 unsigned colNo, StringRef message,
138 bool reportUnexpected = true);
139
140 /// Reports (through \p mgr) any expected diagnostic that was never matched
141 /// by a call to \p process. Returns whether verification succeeded overall,
142 /// i.e. no diagnostic mismatches were recorded either here or by \p
143 /// process.
144 bool verify(raw_ostream &os, SourceMgr &mgr);
145
146private:
147 /// Regex used to recognize '<prefix>-<kind>' comments.
148 Regex expected;
149
150 /// The expected diagnostics for each buffer that has been scanned so far,
151 /// keyed by buffer identifier (i.e. file name).
152 StringMap<SmallVector<ExpectedDiag, 2>> expectedDiagsPerFile;
153
154 /// The expected diagnostics with an '@unknown' location.
155 SmallVector<ExpectedDiag, 2> expectedUnknownLocDiags;
156
157 /// Whether any diagnostic mismatch has been recorded so far.
158 bool ok = true;
159};
160
161} // namespace llvm
162
163#endif // LLVM_SUPPORT_SOURCEMGRDIAGNOSTICVERIFIER_H
This file defines the StringMap class.
#define LLVM_ABI
Definition Compiler.h:211
bool hasLoc(const Instruction &I)
Definition Debugify.cpp:403
ppc ctr loops verify
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
Represents a location in source code.
Definition SMLoc.h:22
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MatchResult
The result of matching a single actual diagnostic against the expected diagnostics recorded for its l...
@ Matched
The diagnostic matched an expected diagnostic (kind and text).
@ Unexpected
The diagnostic did not match any expected diagnostic.
@ Ignored
The diagnostic did not match, but reportUnexpected was false, so nothing was printed and nothing need...
@ NearMiss
The diagnostic's text matched an expected diagnostic, but its kind didn't; a message about this has a...
MutableArrayRef< ExpectedDiag > getExpectedUnknownLocDiags()
Returns the expected diagnostics with an '@unknown' location.
SourceMgrDiagnosticVerifier(const SourceMgrDiagnosticVerifier &)=delete
SourceMgrDiagnosticVerifier & operator=(const SourceMgrDiagnosticVerifier &)=delete
static void printMessage(raw_ostream &os, const SourceMgr &mgr, SMLoc loc, const Twine &msg, ArrayRef< SMRange > ranges={})
Prints an error to os without going through mgr's diagnostic handler, which may be the one feeding th...
static StringRef getDiagKindStr(SourceMgr::DiagKind kind)
Given a diagnostic kind, return a human readable string for it.
SourceMgrDiagnosticVerifier(ArrayRef< StringRef > prefixes={ "expected"})
Recognizes directives starting with any of prefixes (e.g.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:34
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
bool match(Val *V, const Pattern &P)
This is an optimization pass for GlobalISel generic memory operations.
std::optional< Regex > substringRegex
An optional regex matcher, if the expected diagnostic substring was a regex string.
StringRef substring
The substring that is expected to be within the diagnostic.
ExpectedDiag(SourceMgr::DiagKind kind, unsigned lineNo, SMLoc fileLoc, StringRef substring)
SourceMgr::DiagKind kind
The severity of the diagnostic expected.
SMLoc fileLoc
The location of the expected diagnostic within the input file.
unsigned lineNo
The line number the expected diagnostic should be on.
unsigned colNo
The column the expected diagnostic should be at, or 0 if any column matches.
bool matched
A flag indicating if the expected diagnostic has been matched yet.