FileCheck.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //==-- llvm/FileCheck/FileCheck.h --------------------------------*- C++ -*-==//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. /// \file This file has some utilities to use FileCheck as an API
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_FILECHECK_FILECHECK_H
  18. #define LLVM_FILECHECK_FILECHECK_H
  19. #include "llvm/ADT/StringRef.h"
  20. #include "llvm/Support/MemoryBuffer.h"
  21. #include "llvm/Support/Regex.h"
  22. #include "llvm/Support/SourceMgr.h"
  23. #include <bitset>
  24. #include <string>
  25. #include <vector>
  26. namespace llvm {
  27. /// Contains info about various FileCheck options.
  28. struct FileCheckRequest {
  29. std::vector<StringRef> CheckPrefixes;
  30. std::vector<StringRef> CommentPrefixes;
  31. bool NoCanonicalizeWhiteSpace = false;
  32. std::vector<StringRef> ImplicitCheckNot;
  33. std::vector<StringRef> GlobalDefines;
  34. bool AllowEmptyInput = false;
  35. bool AllowUnusedPrefixes = false;
  36. bool MatchFullLines = false;
  37. bool IgnoreCase = false;
  38. bool IsDefaultCheckPrefix = false;
  39. bool EnableVarScope = false;
  40. bool AllowDeprecatedDagOverlap = false;
  41. bool Verbose = false;
  42. bool VerboseVerbose = false;
  43. };
  44. namespace Check {
  45. enum FileCheckKind {
  46. CheckNone = 0,
  47. CheckPlain,
  48. CheckNext,
  49. CheckSame,
  50. CheckNot,
  51. CheckDAG,
  52. CheckLabel,
  53. CheckEmpty,
  54. CheckComment,
  55. /// Indicates the pattern only matches the end of file. This is used for
  56. /// trailing CHECK-NOTs.
  57. CheckEOF,
  58. /// Marks when parsing found a -NOT check combined with another CHECK suffix.
  59. CheckBadNot,
  60. /// Marks when parsing found a -COUNT directive with invalid count value.
  61. CheckBadCount
  62. };
  63. enum FileCheckKindModifier {
  64. /// Modifies directive to perform literal match.
  65. ModifierLiteral = 0,
  66. // The number of modifier.
  67. Size
  68. };
  69. class FileCheckType {
  70. FileCheckKind Kind;
  71. int Count; ///< optional Count for some checks
  72. /// Modifers for the check directive.
  73. std::bitset<FileCheckKindModifier::Size> Modifiers;
  74. public:
  75. FileCheckType(FileCheckKind Kind = CheckNone) : Kind(Kind), Count(1) {}
  76. FileCheckType(const FileCheckType &) = default;
  77. FileCheckType &operator=(const FileCheckType &) = default;
  78. operator FileCheckKind() const { return Kind; }
  79. int getCount() const { return Count; }
  80. FileCheckType &setCount(int C);
  81. bool isLiteralMatch() const {
  82. return Modifiers[FileCheckKindModifier::ModifierLiteral];
  83. }
  84. FileCheckType &setLiteralMatch(bool Literal = true) {
  85. Modifiers.set(FileCheckKindModifier::ModifierLiteral, Literal);
  86. return *this;
  87. }
  88. // \returns a description of \p Prefix.
  89. std::string getDescription(StringRef Prefix) const;
  90. // \returns a description of \p Modifiers.
  91. std::string getModifiersDescription() const;
  92. };
  93. } // namespace Check
  94. /// Summary of a FileCheck diagnostic.
  95. struct FileCheckDiag {
  96. /// What is the FileCheck directive for this diagnostic?
  97. Check::FileCheckType CheckTy;
  98. /// Where is the FileCheck directive for this diagnostic?
  99. SMLoc CheckLoc;
  100. /// What type of match result does this diagnostic describe?
  101. ///
  102. /// A directive's supplied pattern is said to be either expected or excluded
  103. /// depending on whether the pattern must have or must not have a match in
  104. /// order for the directive to succeed. For example, a CHECK directive's
  105. /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
  106. ///
  107. /// There might be more than one match result for a single pattern. For
  108. /// example, there might be several discarded matches
  109. /// (MatchFoundButDiscarded) before either a good match
  110. /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
  111. /// and there might be a fuzzy match (MatchFuzzy) after the latter.
  112. enum MatchType {
  113. /// Indicates a good match for an expected pattern.
  114. MatchFoundAndExpected,
  115. /// Indicates a match for an excluded pattern.
  116. MatchFoundButExcluded,
  117. /// Indicates a match for an expected pattern, but the match is on the
  118. /// wrong line.
  119. MatchFoundButWrongLine,
  120. /// Indicates a discarded match for an expected pattern.
  121. MatchFoundButDiscarded,
  122. /// Indicates an error while processing a match after the match was found
  123. /// for an expected or excluded pattern. The error is specified by \c Note,
  124. /// to which it should be appropriate to prepend "error: " later. The full
  125. /// match itself should be recorded in a preceding diagnostic of a different
  126. /// \c MatchFound match type.
  127. MatchFoundErrorNote,
  128. /// Indicates no match for an excluded pattern.
  129. MatchNoneAndExcluded,
  130. /// Indicates no match for an expected pattern, but this might follow good
  131. /// matches when multiple matches are expected for the pattern, or it might
  132. /// follow discarded matches for the pattern.
  133. MatchNoneButExpected,
  134. /// Indicates no match due to an expected or excluded pattern that has
  135. /// proven to be invalid at match time. The exact problems are usually
  136. /// reported in subsequent diagnostics of the same match type but with
  137. /// \c Note set.
  138. MatchNoneForInvalidPattern,
  139. /// Indicates a fuzzy match that serves as a suggestion for the next
  140. /// intended match for an expected pattern with too few or no good matches.
  141. MatchFuzzy,
  142. } MatchTy;
  143. /// The search range if MatchTy starts with MatchNone, or the match range
  144. /// otherwise.
  145. unsigned InputStartLine;
  146. unsigned InputStartCol;
  147. unsigned InputEndLine;
  148. unsigned InputEndCol;
  149. /// A note to replace the one normally indicated by MatchTy, or the empty
  150. /// string if none.
  151. std::string Note;
  152. FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy,
  153. SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange,
  154. StringRef Note = "");
  155. };
  156. class FileCheckPatternContext;
  157. struct FileCheckString;
  158. /// FileCheck class takes the request and exposes various methods that
  159. /// use information from the request.
  160. class FileCheck {
  161. FileCheckRequest Req;
  162. std::unique_ptr<FileCheckPatternContext> PatternContext;
  163. // C++17 TODO: make this a plain std::vector.
  164. std::unique_ptr<std::vector<FileCheckString>> CheckStrings;
  165. public:
  166. explicit FileCheck(FileCheckRequest Req);
  167. ~FileCheck();
  168. // Combines the check prefixes into a single regex so that we can efficiently
  169. // scan for any of the set.
  170. //
  171. // The semantics are that the longest-match wins which matches our regex
  172. // library.
  173. Regex buildCheckPrefixRegex();
  174. /// Reads the check file from \p Buffer and records the expected strings it
  175. /// contains. Errors are reported against \p SM.
  176. ///
  177. /// Only expected strings whose prefix is one of those listed in \p PrefixRE
  178. /// are recorded. \returns true in case of an error, false otherwise.
  179. ///
  180. /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end)
  181. /// of IDs for source buffers added to \p SM for implicit patterns are
  182. /// recorded in it. The range is empty if there are none.
  183. bool
  184. readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
  185. std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr);
  186. bool ValidateCheckPrefixes();
  187. /// Canonicalizes whitespaces in the file. Line endings are replaced with
  188. /// UNIX-style '\n'.
  189. StringRef CanonicalizeFile(MemoryBuffer &MB,
  190. SmallVectorImpl<char> &OutputBuffer);
  191. /// Checks the input to FileCheck provided in the \p Buffer against the
  192. /// expected strings read from the check file and record diagnostics emitted
  193. /// in \p Diags. Errors are recorded against \p SM.
  194. ///
  195. /// \returns false if the input fails to satisfy the checks.
  196. bool checkInput(SourceMgr &SM, StringRef Buffer,
  197. std::vector<FileCheckDiag> *Diags = nullptr);
  198. };
  199. } // namespace llvm
  200. #endif
  201. #ifdef __GNUC__
  202. #pragma GCC diagnostic pop
  203. #endif