FileCheck.h 8.0 KB

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