LLVM 17.0.0git
FileCheckImpl.h
Go to the documentation of this file.
1//===-- FileCheckImpl.h - Private FileCheck Interface ------------*- 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 the private interfaces of FileCheck. Its purpose is to
10// allow unit testing of FileCheck and to separate the interface from the
11// implementation. It is only meant to be used by FileCheck.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_LIB_FILECHECK_FILECHECKIMPL_H
16#define LLVM_LIB_FILECHECK_FILECHECKIMPL_H
17
18#include "llvm/ADT/StringMap.h"
19#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Error.h"
23#include <map>
24#include <optional>
25#include <string>
26#include <vector>
27
28namespace llvm {
29
30//===----------------------------------------------------------------------===//
31// Numeric substitution handling code.
32//===----------------------------------------------------------------------===//
33
34class ExpressionValue;
35
36/// Type representing the format an expression value should be textualized into
37/// for matching. Used to represent both explicit format specifiers as well as
38/// implicit format from using numeric variables.
40 enum class Kind {
41 /// Denote absence of format. Used for implicit format of literals and
42 /// empty expressions.
44 /// Value is an unsigned integer and should be printed as a decimal number.
46 /// Value is a signed integer and should be printed as a decimal number.
47 Signed,
48 /// Value should be printed as an uppercase hex number.
50 /// Value should be printed as a lowercase hex number.
52 };
53
54private:
55 Kind Value;
56 unsigned Precision = 0;
57 /// printf-like "alternate form" selected.
58 bool AlternateForm = false;
59
60public:
61 /// Evaluates a format to true if it can be used in a match.
62 explicit operator bool() const { return Value != Kind::NoFormat; }
63
64 /// Define format equality: formats are equal if neither is NoFormat and
65 /// their kinds and precision are the same.
66 bool operator==(const ExpressionFormat &Other) const {
67 return Value != Kind::NoFormat && Value == Other.Value &&
68 Precision == Other.Precision && AlternateForm == Other.AlternateForm;
69 }
70
71 bool operator!=(const ExpressionFormat &Other) const {
72 return !(*this == Other);
73 }
74
75 bool operator==(Kind OtherValue) const { return Value == OtherValue; }
76
77 bool operator!=(Kind OtherValue) const { return !(*this == OtherValue); }
78
79 /// \returns the format specifier corresponding to this format as a string.
80 StringRef toString() const;
81
83 explicit ExpressionFormat(Kind Value) : Value(Value), Precision(0){};
84 explicit ExpressionFormat(Kind Value, unsigned Precision)
85 : Value(Value), Precision(Precision){};
86 explicit ExpressionFormat(Kind Value, unsigned Precision, bool AlternateForm)
87 : Value(Value), Precision(Precision), AlternateForm(AlternateForm){};
88
89 /// \returns a wildcard regular expression string that matches any value in
90 /// the format represented by this instance and no other value, or an error
91 /// if the format is NoFormat.
93
94 /// \returns the string representation of \p Value in the format represented
95 /// by this instance, or an error if conversion to this format failed or the
96 /// format is NoFormat.
98
99 /// \returns the value corresponding to string representation \p StrVal
100 /// according to the matching format represented by this instance or an error
101 /// with diagnostic against \p SM if \p StrVal does not correspond to a valid
102 /// and representable value.
104 const SourceMgr &SM) const;
105};
106
107/// Class to represent an overflow error that might result when manipulating a
108/// value.
109class OverflowError : public ErrorInfo<OverflowError> {
110public:
111 static char ID;
112
113 std::error_code convertToErrorCode() const override {
114 return std::make_error_code(std::errc::value_too_large);
115 }
116
117 void log(raw_ostream &OS) const override { OS << "overflow error"; }
118};
119
120/// Class representing a numeric value.
122private:
124 bool Negative;
125
126public:
127 template <class T>
128 explicit ExpressionValue(T Val) : Value(Val), Negative(Val < 0) {}
129
130 bool operator==(const ExpressionValue &Other) const {
131 return Value == Other.Value && isNegative() == Other.isNegative();
132 }
133
134 bool operator!=(const ExpressionValue &Other) const {
135 return !(*this == Other);
136 }
137
138 /// Returns true if value is signed and negative, false otherwise.
139 bool isNegative() const {
140 assert((Value != 0 || !Negative) && "Unexpected negative zero!");
141 return Negative;
142 }
143
144 /// \returns the value as a signed integer or an error if the value is out of
145 /// range.
147
148 /// \returns the value as an unsigned integer or an error if the value is out
149 /// of range.
151
152 /// \returns an unsigned ExpressionValue instance whose value is the absolute
153 /// value to this object's value.
155};
156
157/// Performs operation and \returns its result or an error in case of failure,
158/// such as if an overflow occurs.
159Expected<ExpressionValue> operator+(const ExpressionValue &Lhs,
160 const ExpressionValue &Rhs);
161Expected<ExpressionValue> operator-(const ExpressionValue &Lhs,
162 const ExpressionValue &Rhs);
163Expected<ExpressionValue> operator*(const ExpressionValue &Lhs,
164 const ExpressionValue &Rhs);
165Expected<ExpressionValue> operator/(const ExpressionValue &Lhs,
166 const ExpressionValue &Rhs);
167Expected<ExpressionValue> max(const ExpressionValue &Lhs,
168 const ExpressionValue &Rhs);
169Expected<ExpressionValue> min(const ExpressionValue &Lhs,
170 const ExpressionValue &Rhs);
171
172/// Base class representing the AST of a given expression.
174private:
175 StringRef ExpressionStr;
176
177public:
178 ExpressionAST(StringRef ExpressionStr) : ExpressionStr(ExpressionStr) {}
179
180 virtual ~ExpressionAST() = default;
181
182 StringRef getExpressionStr() const { return ExpressionStr; }
183
184 /// Evaluates and \returns the value of the expression represented by this
185 /// AST or an error if evaluation fails.
186 virtual Expected<ExpressionValue> eval() const = 0;
187
188 /// \returns either the implicit format of this AST, a diagnostic against
189 /// \p SM if implicit formats of the AST's components conflict, or NoFormat
190 /// if the AST has no implicit format (e.g. AST is made up of a single
191 /// literal).
193 getImplicitFormat(const SourceMgr &SM) const {
194 return ExpressionFormat();
195 }
196};
197
198/// Class representing an unsigned literal in the AST of an expression.
200private:
201 /// Actual value of the literal.
203
204public:
205 template <class T>
206 explicit ExpressionLiteral(StringRef ExpressionStr, T Val)
207 : ExpressionAST(ExpressionStr), Value(Val) {}
208
209 /// \returns the literal's value.
210 Expected<ExpressionValue> eval() const override { return Value; }
211};
212
213/// Class to represent an undefined variable error, which quotes that
214/// variable's name when printed.
215class UndefVarError : public ErrorInfo<UndefVarError> {
216private:
217 StringRef VarName;
218
219public:
220 static char ID;
221
222 UndefVarError(StringRef VarName) : VarName(VarName) {}
223
224 StringRef getVarName() const { return VarName; }
225
226 std::error_code convertToErrorCode() const override {
227 return inconvertibleErrorCode();
228 }
229
230 /// Print name of variable associated with this error.
231 void log(raw_ostream &OS) const override {
232 OS << "undefined variable: " << VarName;
233 }
234};
235
236/// Class representing an expression and its matching format.
238private:
239 /// Pointer to AST of the expression.
240 std::unique_ptr<ExpressionAST> AST;
241
242 /// Format to use (e.g. hex upper case letters) when matching the value.
243 ExpressionFormat Format;
244
245public:
246 /// Generic constructor for an expression represented by the given \p AST and
247 /// whose matching format is \p Format.
248 Expression(std::unique_ptr<ExpressionAST> AST, ExpressionFormat Format)
249 : AST(std::move(AST)), Format(Format) {}
250
251 /// \returns pointer to AST of the expression. Pointer is guaranteed to be
252 /// valid as long as this object is.
253 ExpressionAST *getAST() const { return AST.get(); }
254
255 ExpressionFormat getFormat() const { return Format; }
256};
257
258/// Class representing a numeric variable and its associated current value.
260private:
261 /// Name of the numeric variable.
262 StringRef Name;
263
264 /// Format to use for expressions using this variable without an explicit
265 /// format.
266 ExpressionFormat ImplicitFormat;
267
268 /// Value of numeric variable, if defined, or std::nullopt otherwise.
269 std::optional<ExpressionValue> Value;
270
271 /// The input buffer's string from which Value was parsed, or std::nullopt.
272 /// See comments on getStringValue for a discussion of the std::nullopt case.
273 std::optional<StringRef> StrValue;
274
275 /// Line number where this variable is defined, or std::nullopt if defined
276 /// before input is parsed. Used to determine whether a variable is defined on
277 /// the same line as a given use.
278 std::optional<size_t> DefLineNumber;
279
280public:
281 /// Constructor for a variable \p Name with implicit format \p ImplicitFormat
282 /// defined at line \p DefLineNumber or defined before input is parsed if
283 /// \p DefLineNumber is std::nullopt.
284 explicit NumericVariable(StringRef Name, ExpressionFormat ImplicitFormat,
285 std::optional<size_t> DefLineNumber = std::nullopt)
286 : Name(Name), ImplicitFormat(ImplicitFormat),
287 DefLineNumber(DefLineNumber) {}
288
289 /// \returns name of this numeric variable.
290 StringRef getName() const { return Name; }
291
292 /// \returns implicit format of this numeric variable.
293 ExpressionFormat getImplicitFormat() const { return ImplicitFormat; }
294
295 /// \returns this variable's value.
296 std::optional<ExpressionValue> getValue() const { return Value; }
297
298 /// \returns the input buffer's string from which this variable's value was
299 /// parsed, or std::nullopt if the value is not yet defined or was not parsed
300 /// from the input buffer. For example, the value of @LINE is not parsed from
301 /// the input buffer, and some numeric variables are parsed from the command
302 /// line instead.
303 std::optional<StringRef> getStringValue() const { return StrValue; }
304
305 /// Sets value of this numeric variable to \p NewValue, and sets the input
306 /// buffer string from which it was parsed to \p NewStrValue. See comments on
307 /// getStringValue for a discussion of when the latter can be std::nullopt.
309 std::optional<StringRef> NewStrValue = std::nullopt) {
310 Value = NewValue;
311 StrValue = NewStrValue;
312 }
313
314 /// Clears value of this numeric variable, regardless of whether it is
315 /// currently defined or not.
316 void clearValue() {
317 Value = std::nullopt;
318 StrValue = std::nullopt;
319 }
320
321 /// \returns the line number where this variable is defined, if any, or
322 /// std::nullopt if defined before input is parsed.
323 std::optional<size_t> getDefLineNumber() const { return DefLineNumber; }
324};
325
326/// Class representing the use of a numeric variable in the AST of an
327/// expression.
329private:
330 /// Pointer to the class instance for the variable this use is about.
331 NumericVariable *Variable;
332
333public:
335 : ExpressionAST(Name), Variable(Variable) {}
336 /// \returns the value of the variable referenced by this instance.
337 Expected<ExpressionValue> eval() const override;
338
339 /// \returns implicit format of this numeric variable.
341 getImplicitFormat(const SourceMgr &SM) const override {
342 return Variable->getImplicitFormat();
343 }
344};
345
346/// Type of functions evaluating a given binary operation.
348 const ExpressionValue &);
349
350/// Class representing a single binary operation in the AST of an expression.
352private:
353 /// Left operand.
354 std::unique_ptr<ExpressionAST> LeftOperand;
355
356 /// Right operand.
357 std::unique_ptr<ExpressionAST> RightOperand;
358
359 /// Pointer to function that can evaluate this binary operation.
360 binop_eval_t EvalBinop;
361
362public:
363 BinaryOperation(StringRef ExpressionStr, binop_eval_t EvalBinop,
364 std::unique_ptr<ExpressionAST> LeftOp,
365 std::unique_ptr<ExpressionAST> RightOp)
366 : ExpressionAST(ExpressionStr), EvalBinop(EvalBinop) {
367 LeftOperand = std::move(LeftOp);
368 RightOperand = std::move(RightOp);
369 }
370
371 /// Evaluates the value of the binary operation represented by this AST,
372 /// using EvalBinop on the result of recursively evaluating the operands.
373 /// \returns the expression value or an error if an undefined numeric
374 /// variable is used in one of the operands.
375 Expected<ExpressionValue> eval() const override;
376
377 /// \returns the implicit format of this AST, if any, a diagnostic against
378 /// \p SM if the implicit formats of the AST's components conflict, or no
379 /// format if the AST has no implicit format (e.g. AST is made of a single
380 /// literal).
382 getImplicitFormat(const SourceMgr &SM) const override;
383};
384
385class FileCheckPatternContext;
386
387/// Class representing a substitution to perform in the RegExStr string.
389protected:
390 /// Pointer to a class instance holding, among other things, the table with
391 /// the values of live string variables at the start of any given CHECK line.
392 /// Used for substituting string variables with the text they were defined
393 /// as. Expressions are linked to the numeric variables they use at
394 /// parse time and directly access the value of the numeric variable to
395 /// evaluate their value.
397
398 /// The string that needs to be substituted for something else. For a
399 /// string variable this is its name, otherwise this is the whole expression.
401
402 // Index in RegExStr of where to do the substitution.
403 size_t InsertIdx;
404
405public:
407 size_t InsertIdx)
408 : Context(Context), FromStr(VarName), InsertIdx(InsertIdx) {}
409
410 virtual ~Substitution() = default;
411
412 /// \returns the string to be substituted for something else.
413 StringRef getFromString() const { return FromStr; }
414
415 /// \returns the index where the substitution is to be performed in RegExStr.
416 size_t getIndex() const { return InsertIdx; }
417
418 /// \returns a string containing the result of the substitution represented
419 /// by this class instance or an error if substitution failed.
420 virtual Expected<std::string> getResult() const = 0;
421};
422
424public:
426 size_t InsertIdx)
427 : Substitution(Context, VarName, InsertIdx) {}
428
429 /// \returns the text that the string variable in this substitution matched
430 /// when defined, or an error if the variable is undefined.
431 Expected<std::string> getResult() const override;
432};
433
435private:
436 /// Pointer to the class representing the expression whose value is to be
437 /// substituted.
438 std::unique_ptr<Expression> ExpressionPointer;
439
440public:
442 std::unique_ptr<Expression> ExpressionPointer,
443 size_t InsertIdx)
444 : Substitution(Context, ExpressionStr, InsertIdx),
445 ExpressionPointer(std::move(ExpressionPointer)) {}
446
447 /// \returns a string containing the result of evaluating the expression in
448 /// this substitution, or an error if evaluation failed.
449 Expected<std::string> getResult() const override;
450};
451
452//===----------------------------------------------------------------------===//
453// Pattern handling code.
454//===----------------------------------------------------------------------===//
455
456/// Class holding the Pattern global state, shared by all patterns: tables
457/// holding values of variables and whether they are defined or not at any
458/// given time in the matching process.
460 friend class Pattern;
461
462private:
463 /// When matching a given pattern, this holds the value of all the string
464 /// variables defined in previous patterns. In a pattern, only the last
465 /// definition for a given variable is recorded in this table.
466 /// Back-references are used for uses after any the other definition.
467 StringMap<StringRef> GlobalVariableTable;
468
469 /// Map of all string variables defined so far. Used at parse time to detect
470 /// a name conflict between a numeric variable and a string variable when
471 /// the former is defined on a later line than the latter.
472 StringMap<bool> DefinedVariableTable;
473
474 /// When matching a given pattern, this holds the pointers to the classes
475 /// representing the numeric variables defined in previous patterns. When
476 /// matching a pattern all definitions for that pattern are recorded in the
477 /// NumericVariableDefs table in the Pattern instance of that pattern.
478 StringMap<NumericVariable *> GlobalNumericVariableTable;
479
480 /// Pointer to the class instance representing the @LINE pseudo variable for
481 /// easily updating its value.
482 NumericVariable *LineVariable = nullptr;
483
484 /// Vector holding pointers to all parsed numeric variables. Used to
485 /// automatically free them once they are guaranteed to no longer be used.
486 std::vector<std::unique_ptr<NumericVariable>> NumericVariables;
487
488 /// Vector holding pointers to all parsed expressions. Used to automatically
489 /// free the expressions once they are guaranteed to no longer be used.
490 std::vector<std::unique_ptr<Expression>> Expressions;
491
492 /// Vector holding pointers to all substitutions. Used to automatically free
493 /// them once they are guaranteed to no longer be used.
494 std::vector<std::unique_ptr<Substitution>> Substitutions;
495
496public:
497 /// \returns the value of string variable \p VarName or an error if no such
498 /// variable has been defined.
500
501 /// Defines string and numeric variables from definitions given on the
502 /// command line, passed as a vector of [#]VAR=VAL strings in
503 /// \p CmdlineDefines. \returns an error list containing diagnostics against
504 /// \p SM for all definition parsing failures, if any, or Success otherwise.
506 SourceMgr &SM);
507
508 /// Create @LINE pseudo variable. Value is set when pattern are being
509 /// matched.
510 void createLineVariable();
511
512 /// Undefines local variables (variables whose name does not start with a '$'
513 /// sign), i.e. removes them from GlobalVariableTable and from
514 /// GlobalNumericVariableTable and also clears the value of numeric
515 /// variables.
516 void clearLocalVars();
517
518private:
519 /// Makes a new numeric variable and registers it for destruction when the
520 /// context is destroyed.
521 template <class... Types> NumericVariable *makeNumericVariable(Types... args);
522
523 /// Makes a new string substitution and registers it for destruction when the
524 /// context is destroyed.
525 Substitution *makeStringSubstitution(StringRef VarName, size_t InsertIdx);
526
527 /// Makes a new numeric substitution and registers it for destruction when
528 /// the context is destroyed.
529 Substitution *makeNumericSubstitution(StringRef ExpressionStr,
530 std::unique_ptr<Expression> Expression,
531 size_t InsertIdx);
532};
533
534/// Class to represent an error holding a diagnostic with location information
535/// used when printing it.
536class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> {
537private:
538 SMDiagnostic Diagnostic;
539 SMRange Range;
540
541public:
542 static char ID;
543
545 : Diagnostic(Diag), Range(Range) {}
546
547 std::error_code convertToErrorCode() const override {
548 return inconvertibleErrorCode();
549 }
550
551 /// Print diagnostic associated with this error when printing the error.
552 void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); }
553
554 StringRef getMessage() const { return Diagnostic.getMessage(); }
555 SMRange getRange() const { return Range; }
556
557 static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg,
558 SMRange Range = std::nullopt) {
559 return make_error<ErrorDiagnostic>(
560 SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg), Range);
561 }
562
563 static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg) {
564 SMLoc Start = SMLoc::getFromPointer(Buffer.data());
565 SMLoc End = SMLoc::getFromPointer(Buffer.data() + Buffer.size());
566 return get(SM, Start, ErrMsg, SMRange(Start, End));
567 }
568};
569
570class NotFoundError : public ErrorInfo<NotFoundError> {
571public:
572 static char ID;
573
574 std::error_code convertToErrorCode() const override {
575 return inconvertibleErrorCode();
576 }
577
578 /// Print diagnostic associated with this error when printing the error.
579 void log(raw_ostream &OS) const override {
580 OS << "String not found in input";
581 }
582};
583
584/// An error that has already been reported.
585///
586/// This class is designed to support a function whose callers may need to know
587/// whether the function encountered and reported an error but never need to
588/// know the nature of that error. For example, the function has a return type
589/// of \c Error and always returns either \c ErrorReported or \c ErrorSuccess.
590/// That interface is similar to that of a function returning bool to indicate
591/// an error except, in the former case, (1) there is no confusion over polarity
592/// and (2) the caller must either check the result or explicitly ignore it with
593/// a call like \c consumeError.
594class ErrorReported final : public ErrorInfo<ErrorReported> {
595public:
596 static char ID;
597
598 std::error_code convertToErrorCode() const override {
599 return inconvertibleErrorCode();
600 }
601
602 /// Print diagnostic associated with this error when printing the error.
603 void log(raw_ostream &OS) const override {
604 OS << "error previously reported";
605 }
606
607 static inline Error reportedOrSuccess(bool HasErrorReported) {
608 if (HasErrorReported)
609 return make_error<ErrorReported>();
610 return Error::success();
611 }
612};
613
614class Pattern {
615 SMLoc PatternLoc;
616
617 /// A fixed string to match as the pattern or empty if this pattern requires
618 /// a regex match.
619 StringRef FixedStr;
620
621 /// A regex string to match as the pattern or empty if this pattern requires
622 /// a fixed string to match.
623 std::string RegExStr;
624
625 /// Entries in this vector represent a substitution of a string variable or
626 /// an expression in the RegExStr regex at match time. For example, in the
627 /// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
628 /// RegExStr will contain "foobaz" and we'll get two entries in this vector
629 /// that tells us to insert the value of string variable "bar" at offset 3
630 /// and the value of expression "N+1" at offset 6.
631 std::vector<Substitution *> Substitutions;
632
633 /// Maps names of string variables defined in a pattern to the number of
634 /// their parenthesis group in RegExStr capturing their last definition.
635 ///
636 /// E.g. for the pattern "foo[[bar:.*]]baz([[bar]][[QUUX]][[bar:.*]])",
637 /// RegExStr will be "foo(.*)baz(\1<quux value>(.*))" where <quux value> is
638 /// the value captured for QUUX on the earlier line where it was defined, and
639 /// VariableDefs will map "bar" to the third parenthesis group which captures
640 /// the second definition of "bar".
641 ///
642 /// Note: uses std::map rather than StringMap to be able to get the key when
643 /// iterating over values.
644 std::map<StringRef, unsigned> VariableDefs;
645
646 /// Structure representing the definition of a numeric variable in a pattern.
647 /// It holds the pointer to the class instance holding the value and matching
648 /// format of the numeric variable whose value is being defined and the
649 /// number of the parenthesis group in RegExStr to capture that value.
650 struct NumericVariableMatch {
651 /// Pointer to class instance holding the value and matching format of the
652 /// numeric variable being defined.
653 NumericVariable *DefinedNumericVariable;
654
655 /// Number of the parenthesis group in RegExStr that captures the value of
656 /// this numeric variable definition.
657 unsigned CaptureParenGroup;
658 };
659
660 /// Holds the number of the parenthesis group in RegExStr and pointer to the
661 /// corresponding NumericVariable class instance of all numeric variable
662 /// definitions. Used to set the matched value of all those variables.
663 StringMap<NumericVariableMatch> NumericVariableDefs;
664
665 /// Pointer to a class instance holding the global state shared by all
666 /// patterns:
667 /// - separate tables with the values of live string and numeric variables
668 /// respectively at the start of any given CHECK line;
669 /// - table holding whether a string variable has been defined at any given
670 /// point during the parsing phase.
672
673 Check::FileCheckType CheckTy;
674
675 /// Line number for this CHECK pattern or std::nullopt if it is an implicit
676 /// pattern. Used to determine whether a variable definition is made on an
677 /// earlier line to the one with this CHECK.
678 std::optional<size_t> LineNumber;
679
680 /// Ignore case while matching if set to true.
681 bool IgnoreCase = false;
682
683public:
685 std::optional<size_t> Line = std::nullopt)
686 : Context(Context), CheckTy(Ty), LineNumber(Line) {}
687
688 /// \returns the location in source code.
689 SMLoc getLoc() const { return PatternLoc; }
690
691 /// \returns the pointer to the global state for all patterns in this
692 /// FileCheck instance.
694
695 /// \returns whether \p C is a valid first character for a variable name.
696 static bool isValidVarNameStart(char C);
697
698 /// Parsing information about a variable.
702 };
703
704 /// Parses the string at the start of \p Str for a variable name. \returns
705 /// a VariableProperties structure holding the variable name and whether it
706 /// is the name of a pseudo variable, or an error holding a diagnostic
707 /// against \p SM if parsing fail. If parsing was successful, also strips
708 /// \p Str from the variable name.
710 const SourceMgr &SM);
711 /// Parses \p Expr for a numeric substitution block at line \p LineNumber,
712 /// or before input is parsed if \p LineNumber is None. Parameter
713 /// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
714 /// expression and \p Context points to the class instance holding the live
715 /// string and numeric variables. \returns a pointer to the class instance
716 /// representing the expression whose value must be substitued, or an error
717 /// holding a diagnostic against \p SM if parsing fails. If substitution was
718 /// successful, sets \p DefinedNumericVariable to point to the class
719 /// representing the numeric variable defined in this numeric substitution
720 /// block, or std::nullopt if this block does not define any variable.
722 StringRef Expr, std::optional<NumericVariable *> &DefinedNumericVariable,
723 bool IsLegacyLineExpr, std::optional<size_t> LineNumber,
724 FileCheckPatternContext *Context, const SourceMgr &SM);
725 /// Parses the pattern in \p PatternStr and initializes this Pattern instance
726 /// accordingly.
727 ///
728 /// \p Prefix provides which prefix is being matched, \p Req describes the
729 /// global options that influence the parsing such as whitespace
730 /// canonicalization, \p SM provides the SourceMgr used for error reports.
731 /// \returns true in case of an error, false otherwise.
732 bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
733 const FileCheckRequest &Req);
734 struct Match {
735 size_t Pos;
736 size_t Len;
737 };
738 struct MatchResult {
739 std::optional<Match> TheMatch;
741 MatchResult(size_t MatchPos, size_t MatchLen, Error E)
742 : TheMatch(Match{MatchPos, MatchLen}), TheError(std::move(E)) {}
745 };
746 /// Matches the pattern string against the input buffer \p Buffer.
747 ///
748 /// \returns either (1) an error resulting in no match or (2) a match possibly
749 /// with an error encountered while processing the match.
750 ///
751 /// The GlobalVariableTable StringMap in the FileCheckPatternContext class
752 /// instance provides the current values of FileCheck string variables and is
753 /// updated if this match defines new values. Likewise, the
754 /// GlobalNumericVariableTable StringMap in the same class provides the
755 /// current values of FileCheck numeric variables and is updated if this
756 /// match defines new numeric values.
757 MatchResult match(StringRef Buffer, const SourceMgr &SM) const;
758 /// Prints the value of successful substitutions.
759 void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
760 SMRange MatchRange, FileCheckDiag::MatchType MatchTy,
761 std::vector<FileCheckDiag> *Diags) const;
762 void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
763 std::vector<FileCheckDiag> *Diags) const;
764
765 bool hasVariable() const {
766 return !(Substitutions.empty() && VariableDefs.empty());
767 }
769 std::vector<FileCheckDiag> *Diags) const;
770
771 Check::FileCheckType getCheckTy() const { return CheckTy; }
772
773 int getCount() const { return CheckTy.getCount(); }
774
775private:
776 bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
777 void AddBackrefToRegEx(unsigned BackrefNum);
778 /// Computes an arbitrary estimate for the quality of matching this pattern
779 /// at the start of \p Buffer; a distance of zero should correspond to a
780 /// perfect match.
781 unsigned computeMatchDistance(StringRef Buffer) const;
782 /// Finds the closing sequence of a regex variable usage or definition.
783 ///
784 /// \p Str has to point in the beginning of the definition (right after the
785 /// opening sequence). \p SM holds the SourceMgr used for error reporting.
786 /// \returns the offset of the closing sequence within Str, or npos if it
787 /// was not found.
788 static size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
789
790 /// Parses \p Expr for the name of a numeric variable to be defined at line
791 /// \p LineNumber, or before input is parsed if \p LineNumber is None.
792 /// \returns a pointer to the class instance representing that variable,
793 /// creating it if needed, or an error holding a diagnostic against \p SM
794 /// should defining such a variable be invalid.
795 static Expected<NumericVariable *> parseNumericVariableDefinition(
796 StringRef &Expr, FileCheckPatternContext *Context,
797 std::optional<size_t> LineNumber, ExpressionFormat ImplicitFormat,
798 const SourceMgr &SM);
799 /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
800 /// at line \p LineNumber, or before input is parsed if \p LineNumber is
801 /// None. Parameter \p Context points to the class instance holding the live
802 /// string and numeric variables. \returns the pointer to the class instance
803 /// representing that variable if successful, or an error holding a
804 /// diagnostic against \p SM otherwise.
805 static Expected<std::unique_ptr<NumericVariableUse>> parseNumericVariableUse(
806 StringRef Name, bool IsPseudo, std::optional<size_t> LineNumber,
807 FileCheckPatternContext *Context, const SourceMgr &SM);
808 enum class AllowedOperand { LineVar, LegacyLiteral, Any };
809 /// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
810 /// before input is parsed if \p LineNumber is None. Accepts literal values,
811 /// numeric variables and function calls, depending on the value of \p AO.
812 /// \p MaybeInvalidConstraint indicates whether the text being parsed could
813 /// be an invalid constraint. \p Context points to the class instance holding
814 /// the live string and numeric variables. \returns the class representing
815 /// that operand in the AST of the expression or an error holding a
816 /// diagnostic against \p SM otherwise. If \p Expr starts with a "(" this
817 /// function will attempt to parse a parenthesized expression.
818 static Expected<std::unique_ptr<ExpressionAST>>
819 parseNumericOperand(StringRef &Expr, AllowedOperand AO, bool ConstraintParsed,
820 std::optional<size_t> LineNumber,
821 FileCheckPatternContext *Context, const SourceMgr &SM);
822 /// Parses and updates \p RemainingExpr for a binary operation at line
823 /// \p LineNumber, or before input is parsed if \p LineNumber is None. The
824 /// left operand of this binary operation is given in \p LeftOp and \p Expr
825 /// holds the string for the full expression, including the left operand.
826 /// Parameter \p IsLegacyLineExpr indicates whether we are parsing a legacy
827 /// @LINE expression. Parameter \p Context points to the class instance
828 /// holding the live string and numeric variables. \returns the class
829 /// representing the binary operation in the AST of the expression, or an
830 /// error holding a diagnostic against \p SM otherwise.
831 static Expected<std::unique_ptr<ExpressionAST>>
832 parseBinop(StringRef Expr, StringRef &RemainingExpr,
833 std::unique_ptr<ExpressionAST> LeftOp, bool IsLegacyLineExpr,
834 std::optional<size_t> LineNumber, FileCheckPatternContext *Context,
835 const SourceMgr &SM);
836
837 /// Parses a parenthesized expression inside \p Expr at line \p LineNumber, or
838 /// before input is parsed if \p LineNumber is None. \p Expr must start with
839 /// a '('. Accepts both literal values and numeric variables. Parameter \p
840 /// Context points to the class instance holding the live string and numeric
841 /// variables. \returns the class representing that operand in the AST of the
842 /// expression or an error holding a diagnostic against \p SM otherwise.
843 static Expected<std::unique_ptr<ExpressionAST>>
844 parseParenExpr(StringRef &Expr, std::optional<size_t> LineNumber,
845 FileCheckPatternContext *Context, const SourceMgr &SM);
846
847 /// Parses \p Expr for an argument list belonging to a call to function \p
848 /// FuncName at line \p LineNumber, or before input is parsed if \p LineNumber
849 /// is None. Parameter \p FuncLoc is the source location used for diagnostics.
850 /// Parameter \p Context points to the class instance holding the live string
851 /// and numeric variables. \returns the class representing that call in the
852 /// AST of the expression or an error holding a diagnostic against \p SM
853 /// otherwise.
854 static Expected<std::unique_ptr<ExpressionAST>>
855 parseCallExpr(StringRef &Expr, StringRef FuncName,
856 std::optional<size_t> LineNumber,
857 FileCheckPatternContext *Context, const SourceMgr &SM);
858};
859
860//===----------------------------------------------------------------------===//
861// Check Strings.
862//===----------------------------------------------------------------------===//
863
864/// A check that we found in the input file.
866 /// The pattern to match.
868
869 /// Which prefix name this check matched.
871
872 /// The location in the match file that the check string was specified.
874
875 /// All of the strings that are disallowed from occurring between this match
876 /// string and the previous one (or start of file).
877 std::vector<Pattern> DagNotStrings;
878
880 : Pat(P), Prefix(S), Loc(L) {}
881
882 /// Matches check string and its "not strings" and/or "dag strings".
883 size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
884 size_t &MatchLen, FileCheckRequest &Req,
885 std::vector<FileCheckDiag> *Diags) const;
886
887 /// Verifies that there is a single line in the given \p Buffer. Errors are
888 /// reported against \p SM.
889 bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
890 /// Verifies that there is no newline in the given \p Buffer. Errors are
891 /// reported against \p SM.
892 bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
893 /// Verifies that none of the strings in \p NotStrings are found in the given
894 /// \p Buffer. Errors are reported against \p SM and diagnostics recorded in
895 /// \p Diags according to the verbosity level set in \p Req.
896 bool CheckNot(const SourceMgr &SM, StringRef Buffer,
897 const std::vector<const Pattern *> &NotStrings,
898 const FileCheckRequest &Req,
899 std::vector<FileCheckDiag> *Diags) const;
900 /// Matches "dag strings" and their mixed "not strings".
901 size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
902 std::vector<const Pattern *> &NotStrings,
903 const FileCheckRequest &Req,
904 std::vector<FileCheckDiag> *Diags) const;
905};
906
907} // namespace llvm
908
909#endif
This file defines the StringMap class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
bool End
Definition: ELF_riscv.cpp:464
nvptx lower args
LLVMContext & Context
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Definition: Any.h:28
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Class representing a single binary operation in the AST of an expression.
BinaryOperation(StringRef ExpressionStr, binop_eval_t EvalBinop, std::unique_ptr< ExpressionAST > LeftOp, std::unique_ptr< ExpressionAST > RightOp)
Expected< ExpressionFormat > getImplicitFormat(const SourceMgr &SM) const override
Definition: FileCheck.cpp:389
Expected< ExpressionValue > eval() const override
Evaluates the value of the binary operation represented by this AST, using EvalBinop on the result of...
Definition: FileCheck.cpp:370
Class to represent an error holding a diagnostic with location information used when printing it.
StringRef getMessage() const
ErrorDiagnostic(SMDiagnostic &&Diag, SMRange Range)
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
void log(raw_ostream &OS) const override
Print diagnostic associated with this error when printing the error.
SMRange getRange() const
static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg)
static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg, SMRange Range=std::nullopt)
Base class for user error types.
Definition: Error.h:348
An error that has already been reported.
static Error reportedOrSuccess(bool HasErrorReported)
void log(raw_ostream &OS) const override
Print diagnostic associated with this error when printing the error.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
Base class representing the AST of a given expression.
virtual Expected< ExpressionValue > eval() const =0
Evaluates and.
ExpressionAST(StringRef ExpressionStr)
StringRef getExpressionStr() const
virtual ~ExpressionAST()=default
virtual Expected< ExpressionFormat > getImplicitFormat(const SourceMgr &SM) const
Class representing an unsigned literal in the AST of an expression.
ExpressionLiteral(StringRef ExpressionStr, T Val)
Expected< ExpressionValue > eval() const override
Class representing a numeric value.
bool operator!=(const ExpressionValue &Other) const
bool operator==(const ExpressionValue &Other) const
ExpressionValue getAbsolute() const
Definition: FileCheck.cpp:185
bool isNegative() const
Returns true if value is signed and negative, false otherwise.
Expected< int64_t > getSignedValue() const
Definition: FileCheck.cpp:167
Expected< uint64_t > getUnsignedValue() const
Definition: FileCheck.cpp:178
Class representing an expression and its matching format.
ExpressionFormat getFormat() const
Expression(std::unique_ptr< ExpressionAST > AST, ExpressionFormat Format)
Generic constructor for an expression represented by the given AST and whose matching format is Forma...
ExpressionAST * getAST() const
Class holding the Pattern global state, shared by all patterns: tables holding values of variables an...
Error defineCmdlineVariables(ArrayRef< StringRef > CmdlineDefines, SourceMgr &SM)
Defines string and numeric variables from definitions given on the command line, passed as a vector o...
Definition: FileCheck.cpp:2634
void createLineVariable()
Create @LINE pseudo variable.
Definition: FileCheck.cpp:1858
Expected< StringRef > getPatternVarValue(StringRef VarName)
Definition: FileCheck.cpp:1508
void clearLocalVars()
Undefines local variables (variables whose name does not start with a '$' sign), i....
Definition: FileCheck.cpp:2772
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
void log(raw_ostream &OS) const override
Print diagnostic associated with this error when printing the error.
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:415
NumericSubstitution(FileCheckPatternContext *Context, StringRef ExpressionStr, std::unique_ptr< Expression > ExpressionPointer, size_t InsertIdx)
Class representing the use of a numeric variable in the AST of an expression.
NumericVariableUse(StringRef Name, NumericVariable *Variable)
Expected< ExpressionValue > eval() const override
Definition: FileCheck.cpp:362
Expected< ExpressionFormat > getImplicitFormat(const SourceMgr &SM) const override
Class representing a numeric variable and its associated current value.
void clearValue()
Clears value of this numeric variable, regardless of whether it is currently defined or not.
ExpressionFormat getImplicitFormat() const
StringRef getName() const
std::optional< StringRef > getStringValue() const
std::optional< ExpressionValue > getValue() const
NumericVariable(StringRef Name, ExpressionFormat ImplicitFormat, std::optional< size_t > DefLineNumber=std::nullopt)
Constructor for a variable Name with implicit format ImplicitFormat defined at line DefLineNumber or ...
void setValue(ExpressionValue NewValue, std::optional< StringRef > NewStrValue=std::nullopt)
Sets value of this numeric variable to NewValue, and sets the input buffer string from which it was p...
std::optional< size_t > getDefLineNumber() const
Class to represent an overflow error that might result when manipulating a value.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
static Expected< VariableProperties > parseVariable(StringRef &Str, const SourceMgr &SM)
Parses the string at the start of Str for a variable name.
Definition: FileCheck.cpp:437
MatchResult match(StringRef Buffer, const SourceMgr &SM) const
Matches the pattern string against the input buffer Buffer.
Definition: FileCheck.cpp:1223
void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, std::vector< FileCheckDiag > *Diags) const
Definition: FileCheck.cpp:1461
void printSubstitutions(const SourceMgr &SM, StringRef Buffer, SMRange MatchRange, FileCheckDiag::MatchType MatchTy, std::vector< FileCheckDiag > *Diags) const
Prints the value of successful substitutions.
Definition: FileCheck.cpp:1353
bool hasVariable() const
SMLoc getLoc() const
FileCheckPatternContext * getContext() const
static Expected< std::unique_ptr< Expression > > parseNumericSubstitutionBlock(StringRef Expr, std::optional< NumericVariable * > &DefinedNumericVariable, bool IsLegacyLineExpr, std::optional< size_t > LineNumber, FileCheckPatternContext *Context, const SourceMgr &SM)
Parses Expr for a numeric substitution block at line LineNumber, or before input is parsed if LineNum...
Definition: FileCheck.cpp:763
Pattern(Check::FileCheckType Ty, FileCheckPatternContext *Context, std::optional< size_t > Line=std::nullopt)
void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy, std::vector< FileCheckDiag > *Diags) const
Definition: FileCheck.cpp:1387
static bool isValidVarNameStart(char C)
Definition: FileCheck.cpp:434
int getCount() const
Check::FileCheckType getCheckTy() const
bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM, const FileCheckRequest &Req)
Parses the pattern in PatternStr and initializes this Pattern instance accordingly.
Definition: FileCheck.cpp:912
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
StringRef getMessage() const
Definition: SourceMgr.h:311
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Definition: SourceMgr.cpp:484
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
Represents a range in source code.
Definition: SMLoc.h:48
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition: SourceMgr.h:31
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}) const
Return an SMDiagnostic at the specified location with the specified string.
Definition: SourceMgr.cpp:274
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
StringSubstitution(FileCheckPatternContext *Context, StringRef VarName, size_t InsertIdx)
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:426
Class representing a substitution to perform in the RegExStr string.
virtual ~Substitution()=default
Substitution(FileCheckPatternContext *Context, StringRef VarName, size_t InsertIdx)
StringRef getFromString() const
size_t getIndex() const
FileCheckPatternContext * Context
Pointer to a class instance holding, among other things, the table with the values of live string var...
StringRef FromStr
The string that needs to be substituted for something else.
virtual Expected< std::string > getResult() const =0
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Class to represent an undefined variable error, which quotes that variable's name when printed.
UndefVarError(StringRef VarName)
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
StringRef getVarName() const
void log(raw_ostream &OS) const override
Print name of variable associated with this error.
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2174
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:354
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:334
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1946
InstructionCost operator/(const InstructionCost &LHS, const InstructionCost &RHS)
APInt operator-(APInt)
Definition: APInt.h:2127
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2132
Definition: BitVector.h:858
Type representing the format an expression value should be textualized into for matching.
Definition: FileCheckImpl.h:39
StringRef toString() const
Definition: FileCheck.cpp:31
bool operator!=(const ExpressionFormat &Other) const
Definition: FileCheckImpl.h:71
bool operator==(Kind OtherValue) const
Definition: FileCheckImpl.h:75
Expected< std::string > getWildcardRegex() const
Definition: FileCheck.cpp:47
ExpressionFormat(Kind Value)
Definition: FileCheckImpl.h:83
@ HexLower
Value should be printed as a lowercase hex number.
@ HexUpper
Value should be printed as an uppercase hex number.
@ Signed
Value is a signed integer and should be printed as a decimal number.
@ Unsigned
Value is an unsigned integer and should be printed as a decimal number.
@ NoFormat
Denote absence of format.
Expected< std::string > getMatchingString(ExpressionValue Value) const
Definition: FileCheck.cpp:80
ExpressionFormat(Kind Value, unsigned Precision)
Definition: FileCheckImpl.h:84
bool operator!=(Kind OtherValue) const
Definition: FileCheckImpl.h:77
bool operator==(const ExpressionFormat &Other) const
Define format equality: formats are equal if neither is NoFormat and their kinds and precision are th...
Definition: FileCheckImpl.h:66
ExpressionFormat(Kind Value, unsigned Precision, bool AlternateForm)
Definition: FileCheckImpl.h:86
Expected< ExpressionValue > valueFromStringRepr(StringRef StrVal, const SourceMgr &SM) const
Definition: FileCheck.cpp:128
MatchType
What type of match result does this diagnostic describe?
Definition: FileCheck.h:130
Contains info about various FileCheck options.
Definition: FileCheck.h:30
A check that we found in the input file.
bool CheckNext(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is a single line in the given Buffer.
Definition: FileCheck.cpp:2342
Pattern Pat
The pattern to match.
bool CheckSame(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is no newline in the given Buffer.
Definition: FileCheck.cpp:2381
size_t CheckDag(const SourceMgr &SM, StringRef Buffer, std::vector< const Pattern * > &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Matches "dag strings" and their mixed "not strings".
Definition: FileCheck.cpp:2422
FileCheckString(const Pattern &P, StringRef S, SMLoc L)
SMLoc Loc
The location in the match file that the check string was specified.
StringRef Prefix
Which prefix name this check matched.
std::vector< Pattern > DagNotStrings
All of the strings that are disallowed from occurring between this match string and the previous one ...
bool CheckNot(const SourceMgr &SM, StringRef Buffer, const std::vector< const Pattern * > &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Verifies that none of the strings in NotStrings are found in the given Buffer.
Definition: FileCheck.cpp:2403
MatchResult(Match M, Error E)
MatchResult(size_t MatchPos, size_t MatchLen, Error E)
std::optional< Match > TheMatch
Parsing information about a variable.