# Changeset View

Changeset View

# Standalone View

Standalone View

# llvm/include/llvm/Support/FileCheck.h

Show All 34 Lines | 26 | struct FileCheckRequest { | |||
---|---|---|---|---|---|

35 | bool Verbose = false; | 35 | bool Verbose = false; | ||

36 | bool VerboseVerbose = false; | 36 | bool VerboseVerbose = false; | ||

37 | }; | 37 | }; | ||

38 | 38 | | |||

39 | //===----------------------------------------------------------------------===// | 39 | //===----------------------------------------------------------------------===// | ||

40 | // Numeric substitution handling code. | 40 | // Numeric substitution handling code. | ||

41 | //===----------------------------------------------------------------------===// | 41 | //===----------------------------------------------------------------------===// | ||

42 | 42 | | |||

43 | class FileCheckExpressionValue; | ||||

44 | | ||||

43 | /// Bitfield representing the format an expression value should be printed into | 45 | /// Bitfield representing the format an expression value should be printed into | ||

44 | /// for matching. Used to represent both explicit format specifiers as well as | 46 | /// for matching. Used to represent both explicit format specifiers as well as | ||

45 | /// implicit format from using numeric variables. | 47 | /// implicit format from using numeric variables. | ||

46 | struct FileCheckExpressionFormat { | 48 | struct FileCheckExpressionFormat { | ||

49 | /// Value is a signed integer. | ||||

50 | unsigned Signed : 1; | ||||

47 | /// Value should be printed as hex number. | 51 | /// Value should be printed as hex number. | ||

48 | unsigned Hex : 1; | 52 | unsigned Hex : 1; | ||

49 | /// Value should be printed using upper case letters, only used for hex | 53 | /// Value should be printed using upper case letters, only used for hex | ||

50 | /// numbers. | 54 | /// numbers. | ||

51 | unsigned Cap : 1; | 55 | unsigned Cap : 1; | ||

52 | 56 | | |||

53 | /// When unset, denote absence of format and thus that all of the other | 57 | /// When unset, denote absence of format and thus that all of the other | ||

54 | /// fields are to be ignored. Used for implicit format of literals and empty | 58 | /// fields are to be ignored. Used for implicit format of literals and empty | ||

Show All 9 Lines | 67 | bool operator!=(const FileCheckExpressionFormat &other) { | |||

64 | return !(*this == other); | 68 | return !(*this == other); | ||

65 | } | 69 | } | ||

66 | 70 | | |||

67 | /// \returns wildcard regexp StringRef to match any value in the format | 71 | /// \returns wildcard regexp StringRef to match any value in the format | ||

68 | /// represented by this instance. | 72 | /// represented by this instance. | ||

69 | StringRef getWildcardRegex() const; | 73 | StringRef getWildcardRegex() const; | ||

70 | 74 | | |||

71 | /// \returns the string representation of \p Value in the format represented | 75 | /// \returns the string representation of \p Value in the format represented | ||

72 | /// by this instance. | 76 | /// by this instance, or an error if conversion to this format failed. | ||

73 | std::string getMatchingString(uint64_t Value) const; | 77 | Expected<std::string> | ||

78 | getMatchingString(FileCheckExpressionValue Value) const; | ||||

74 | 79 | | |||

75 | /// \returns the value corresponding to string representation \p StrVal | 80 | /// \returns the value corresponding to string representation \p StrVal | ||

76 | /// according to the matching format represented by this instance or an error | 81 | /// according to the matching format represented by this instance or an error | ||

77 | /// with diagnostic against \p SM if \p StrVal does not correspond to a valid | 82 | /// with diagnostic against \p SM if \p StrVal does not correspond to a valid | ||

78 | /// and representable value. | 83 | /// and representable value. | ||

79 | Expected<uint64_t> valueFromStringRepr(StringRef StrVal, | 84 | Expected<FileCheckExpressionValue> | ||

80 | const SourceMgr &SM) const; | 85 | valueFromStringRepr(StringRef StrVal, const SourceMgr &SM) const; | ||

81 | }; | 86 | }; | ||

82 | 87 | | |||

83 | /// Initializer for an expression without format. | 88 | /// Initializer for an expression without format. | ||

84 | const FileCheckExpressionFormat FormatNone = {0, 0, 0, 0}; | 89 | const FileCheckExpressionFormat FormatNone = {0, 0, 0, 0, 0}; | ||

85 | /// Initializer for an expression matched as unsigned value. | 90 | /// Initializer for an expression matched as unsigned value. | ||

86 | const FileCheckExpressionFormat FormatUnsigned = {0, 0, 1, 0}; | 91 | const FileCheckExpressionFormat FormatUnsigned = {0, 0, 0, 1, 0}; | ||

92 | /// Initializer for an expression matched as signed value. | ||||

93 | const FileCheckExpressionFormat FormatSigned = {1, 0, 0, 1, 0}; | ||||

87 | /// Initializer for an expression matched as lower case hex value. | 94 | /// Initializer for an expression matched as lower case hex value. | ||

88 | const FileCheckExpressionFormat FormatLowHex = {1, 0, 1, 0}; | 95 | const FileCheckExpressionFormat FormatLowHex = {0, 1, 0, 1, 0}; | ||

89 | /// Initializer for an expression matched as capital case hex value. | 96 | /// Initializer for an expression matched as capital case hex value. | ||

90 | const FileCheckExpressionFormat FormatCapHex = {1, 1, 1, 0}; | 97 | const FileCheckExpressionFormat FormatCapHex = {0, 1, 1, 1, 0}; | ||

98 | | ||||

99 | enum ValueErrorType { ValOverflow, ValPromotion, ValStringConversion }; | ||||

100 | | ||||

101 | /// Class to represent an error when manipulating a value. Possible value | ||||

102 | /// errors are overflow, promotion and string conversion errors. | ||||

103 | class FileCheckValueError : public ErrorInfo<FileCheckValueError> { | ||||

104 | private: | ||||

105 | /// Type of value error. | ||||

106 | enum ValueErrorType Type; | ||||

107 | | ||||

108 | public: | ||||

109 | static char ID; | ||||

110 | | ||||

111 | FileCheckValueError(ValueErrorType Type) : Type(Type) {} | ||||

112 | | ||||

113 | ValueErrorType getType() const { return Type; } | ||||

114 | | ||||

115 | /// \returns string describing this value error. | ||||

116 | const char *getMsg() const { | ||||

117 | switch (Type) { | ||||

118 | case ValOverflow: | ||||

119 | return "overflow"; | ||||

120 | case ValPromotion: | ||||

121 | return "promotion"; | ||||

122 | case ValStringConversion: | ||||

123 | return "string conversion"; | ||||

124 | } | ||||

125 | } | ||||

126 | | ||||

127 | std::error_code convertToErrorCode() const override { | ||||

128 | return inconvertibleErrorCode(); | ||||

129 | } | ||||

130 | | ||||

131 | /// Print type of value conversion that failed. | ||||

132 | void log(raw_ostream &OS) const override { OS << Twine(getMsg()) + " error"; } | ||||

133 | }; | ||||

134 | | ||||

135 | /// Class representing a numeric value. | ||||

136 | class FileCheckExpressionValue { | ||||

137 | private: | ||||

138 | union { | ||||

139 | int64_t SignedValue; | ||||

140 | uint64_t UnsignedValue; | ||||

141 | }; | ||||

142 | | ||||

143 | /// Whether value is signed (and thus is stored in SignedValue) or not (in | ||||

144 | /// which case it is stored in UnsignedValue). | ||||

145 | bool Signed; | ||||

146 | | ||||

147 | public: | ||||

148 | /// Constructor for a signed value. | ||||

149 | explicit FileCheckExpressionValue(int64_t Val) | ||||

150 | : SignedValue(Val), Signed(true) {} | ||||

151 | | ||||

152 | /// Constructor for an unsigned value. | ||||

153 | explicit FileCheckExpressionValue(uint64_t Val) | ||||

154 | : UnsignedValue(Val), Signed(false) {} | ||||

155 | | ||||

156 | /// Define equality to be true only if both values are valid and they have | ||||

157 | /// the same signedness and corresponding value. | ||||

158 | bool operator==(const FileCheckExpressionValue &other); | ||||

159 | bool operator!=(const FileCheckExpressionValue &other) { | ||||

160 | return !(*this == other); | ||||

161 | } | ||||

162 | | ||||

163 | bool isSigned() const { return Signed; } | ||||

164 | | ||||

165 | /// \returns the signed value. Must only be called if value is signed in the | ||||

166 | /// first place. | ||||

167 | int64_t getSignedValue() const { | ||||

168 | assert(Signed); | ||||

169 | return SignedValue; | ||||

170 | } | ||||

171 | | ||||

172 | /// \returns the unsigned value. Must only be called if value is unsigned in | ||||

173 | /// the first place. | ||||

174 | uint64_t getUnsignedValue() const { | ||||

175 | assert(!Signed); | ||||

176 | return UnsignedValue; | ||||

177 | } | ||||

178 | | ||||

179 | /// Converts this value to a signed value. \returns an error if not possible | ||||

180 | /// (original value was not within range for a signed integer). | ||||

181 | Error convertSigned(); | ||||

182 | | ||||

183 | /// Converts this value to an unsigned value. \returns an error if not | ||||

184 | /// possible (original value was not within range for an unsigned integer). | ||||

185 | Error convertUnsigned(); | ||||

186 | | ||||

187 | /// Performs operation and \returns its result or an error in case of | ||||

188 | /// overflow. | ||||

189 | friend Expected<FileCheckExpressionValue> | ||||

190 | operator+(const FileCheckExpressionValue &lhs, | ||||

191 | const FileCheckExpressionValue &rhs); | ||||

192 | friend Expected<FileCheckExpressionValue> | ||||

193 | operator-(const FileCheckExpressionValue &lhs, | ||||

194 | const FileCheckExpressionValue &rhs); | ||||

195 | }; | ||||

91 | 196 | | |||

92 | /// Base class representing the AST of a given expression. | 197 | /// Base class representing the AST of a given expression. | ||

93 | class FileCheckExpressionAST { | 198 | class FileCheckExpressionAST { | ||

94 | public: | 199 | public: | ||

95 | virtual ~FileCheckExpressionAST() = default; | 200 | virtual ~FileCheckExpressionAST() = default; | ||

96 | 201 | | |||

97 | /// Evaluates and \returns the value of the expression represented by this | 202 | /// Evaluates and \returns the value of the expression represented by this | ||

98 | /// AST or an error if evaluation fails. | 203 | /// AST or an error if evaluation fails. | ||

99 | virtual Expected<uint64_t> eval() const = 0; | 204 | virtual Expected<FileCheckExpressionValue> eval() const = 0; | ||

100 | 205 | | |||

101 | /// \returns implicit format of this AST, FormatConflict if implicit formats | 206 | /// \returns implicit format of this AST, FormatConflict if implicit formats | ||

102 | /// of the AST's components conflict and FormatNone if the AST has no | 207 | /// of the AST's components conflict and FormatNone if the AST has no | ||

103 | /// implicit format (e.g. AST is made of a single literal). | 208 | /// implicit format (e.g. AST is made of a single literal). | ||

104 | virtual FileCheckExpressionFormat getImplicitFormat() const = 0; | 209 | virtual FileCheckExpressionFormat getImplicitFormat() const = 0; | ||

105 | }; | 210 | }; | ||

106 | 211 | | |||

107 | /// Class representing a literal in the AST of an expression. | 212 | /// Class representing a literal in the AST of an expression. | ||

108 | class FileCheckExpressionLiteral : public FileCheckExpressionAST { | 213 | class FileCheckExpressionLiteral : public FileCheckExpressionAST { | ||

109 | private: | 214 | private: | ||

110 | /// Actual value of the literal. | 215 | /// Actual value of the literal. | ||

111 | uint64_t Value; | 216 | FileCheckExpressionValue Value; | ||

112 | 217 | | |||

113 | public: | 218 | public: | ||

114 | /// Constructor for a literal. | 219 | /// Constructor for a signed literal. | ||

220 | FileCheckExpressionLiteral(int64_t Val) : Value(Val) {} | ||||

221 | | ||||

222 | /// Constructor for an unsigned literal. | ||||

115 | FileCheckExpressionLiteral(uint64_t Val) : Value(Val) {} | 223 | FileCheckExpressionLiteral(uint64_t Val) : Value(Val) {} | ||

116 | 224 | | |||

117 | /// \returns the literal's value. | 225 | /// \returns the literal's value. | ||

118 | Expected<uint64_t> eval() const { return Value; } | 226 | Expected<FileCheckExpressionValue> eval() const { return Value; } | ||

119 | 227 | | |||

120 | /// \returns implicit format of this literal, therefore FormatNone. | 228 | /// \returns implicit format of this literal, therefore FormatNone. | ||

121 | FileCheckExpressionFormat getImplicitFormat() const { return FormatNone; } | 229 | FileCheckExpressionFormat getImplicitFormat() const { return FormatNone; } | ||

122 | }; | 230 | }; | ||

123 | 231 | | |||

124 | /// Class to represent an undefined variable error which prints that variable's | 232 | /// Class to represent an undefined variable error which prints that variable's | ||

125 | /// name between quotes when printed. | 233 | /// name between quotes when printed. | ||

126 | class FileCheckUndefVarError : public ErrorInfo<FileCheckUndefVarError> { | 234 | class FileCheckUndefVarError : public ErrorInfo<FileCheckUndefVarError> { | ||

▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Line(s) | 288 | private: | |||

182 | StringRef Name; | 290 | StringRef Name; | ||

183 | 291 | | |||

184 | /// Pointer to expression defining this numeric variable. Null for pseudo | 292 | /// Pointer to expression defining this numeric variable. Null for pseudo | ||

185 | /// variable whose value is known at parse time (e.g. @LINE pseudo variable) | 293 | /// variable whose value is known at parse time (e.g. @LINE pseudo variable) | ||

186 | /// or cleared local variable. If expression is empty Expression points to a | 294 | /// or cleared local variable. If expression is empty Expression points to a | ||

187 | /// FileCheckExpression with a null AST. | 295 | /// FileCheckExpression with a null AST. | ||

188 | FileCheckExpression *Expression; | 296 | FileCheckExpression *Expression; | ||

189 | 297 | | |||

190 | /// Value of numeric variable, if defined, or None otherwise. | 298 | /// Value of numeric variable. | ||

191 | Optional<uint64_t> Value; | 299 | Optional<FileCheckExpressionValue> Value; | ||

192 | 300 | | |||

193 | /// Line number where this variable is defined. Used to determine whether a | 301 | /// Line number where this variable is defined. Used to determine whether a | ||

194 | /// variable is defined on the same line as a given use. | 302 | /// variable is defined on the same line as a given use. | ||

195 | size_t DefLineNumber; | 303 | size_t DefLineNumber; | ||

196 | 304 | | |||

197 | public: | 305 | public: | ||

198 | /// Constructor for a variable \p Name defined at line \p DefLineNumber to | 306 | /// Constructor for a variable \p Name defined at line \p DefLineNumber to | ||

199 | /// the expression represented by \p Expression. | 307 | /// the expression represented by \p Expression. | ||

200 | FileCheckNumericVariable(size_t DefLineNumber, StringRef Name, | 308 | FileCheckNumericVariable(size_t DefLineNumber, StringRef Name, | ||

201 | FileCheckExpression *Expression) | 309 | FileCheckExpression *Expression) | ||

202 | : Name(Name), Expression(Expression), DefLineNumber(DefLineNumber) {} | 310 | : Name(Name), Expression(Expression), DefLineNumber(DefLineNumber) {} | ||

203 | 311 | | |||

204 | /// Constructor for numeric variable \p Name with a known \p Value at parse | 312 | /// Constructor for numeric variable \p Name with a known \p Value at parse | ||

205 | /// time (e.g. the @LINE numeric variable). | 313 | /// time (e.g. the @LINE numeric variable). | ||

206 | FileCheckNumericVariable(StringRef Name, uint64_t Value) | 314 | FileCheckNumericVariable(StringRef Name, FileCheckExpressionValue &Value) | ||

207 | : Name(Name), Expression(nullptr), Value(Value), DefLineNumber(0) {} | 315 | : Name(Name), Expression(nullptr), Value(Value), DefLineNumber(0) {} | ||

208 | 316 | | |||

209 | /// \returns name of this numeric variable. | 317 | /// \returns name of this numeric variable. | ||

210 | StringRef getName() const { return Name; } | 318 | StringRef getName() const { return Name; } | ||

211 | 319 | | |||

212 | /// \returns expression associated with this numeric variable. | 320 | /// \returns expression associated with this numeric variable. | ||

213 | FileCheckExpression *getExpression() const { return Expression; } | 321 | FileCheckExpression *getExpression() const { return Expression; } | ||

214 | 322 | | |||

215 | /// \returns this variable's value. | 323 | /// \returns this variable's value. | ||

216 | Expected<uint64_t> eval() const; | 324 | Expected<FileCheckExpressionValue> eval() const; | ||

217 | 325 | | |||

218 | /// \returns whether this variable's value is known at match time, when | 326 | /// \returns whether this variable's value is known at match time, when | ||

219 | /// performing the substitutions. | 327 | /// performing the substitutions. | ||

220 | bool isMatchTimeKnown() const; | 328 | bool isMatchTimeKnown() const; | ||

221 | 329 | | |||

222 | /// \returns implicit format of this numeric variable. | 330 | /// \returns implicit format of this numeric variable. | ||

223 | FileCheckExpressionFormat getImplicitFormat() const; | 331 | FileCheckExpressionFormat getImplicitFormat() const; | ||

224 | 332 | | |||

225 | /// Sets value of this numeric variable if not defined. \returns whether the | 333 | /// Sets value of this numeric variable if not defined. \returns whether the | ||

226 | /// variable was already defined. | 334 | /// variable was already defined. | ||

227 | bool setValue(uint64_t Value); | 335 | bool setValue(FileCheckExpressionValue Value); | ||

228 | 336 | | |||

229 | /// Clears value of this numeric variable. \returns whether the variable was | 337 | /// Clears value of this numeric variable. \returns whether the variable was | ||

230 | /// already undefined. | 338 | /// already undefined. | ||

231 | bool clearValue(); | 339 | bool clearValue(); | ||

232 | 340 | | |||

233 | /// \returns the line number where this variable is defined. | 341 | /// \returns the line number where this variable is defined. | ||

234 | size_t getDefLineNumber() { return DefLineNumber; } | 342 | size_t getDefLineNumber() { return DefLineNumber; } | ||

235 | }; | 343 | }; | ||

236 | 344 | | |||

237 | /// Type of functions evaluating a given binary operation. | 345 | /// Type of functions evaluating a given binary operation. | ||

238 | using binop_eval_t = uint64_t (*)(uint64_t, uint64_t); | 346 | using binop_eval_t = Expected<FileCheckExpressionValue> (*)( | ||

347 | const FileCheckExpressionValue &, const FileCheckExpressionValue &); | ||||

239 | 348 | | |||

240 | /// Class representing a single binary operation in the AST of an expression. | 349 | /// Class representing a single binary operation in the AST of an expression. | ||

241 | class FileCheckASTBinop : public FileCheckExpressionAST { | 350 | class FileCheckASTBinop : public FileCheckExpressionAST { | ||

242 | private: | 351 | private: | ||

243 | /// Left operand. | 352 | /// Left operand. | ||

244 | std::shared_ptr<FileCheckExpressionAST> LeftOp; | 353 | std::shared_ptr<FileCheckExpressionAST> LeftOp; | ||

245 | 354 | | |||

246 | /// Right operand. | 355 | /// Right operand. | ||

247 | std::shared_ptr<FileCheckExpressionAST> RightOp; | 356 | std::shared_ptr<FileCheckExpressionAST> RightOp; | ||

248 | 357 | | |||

249 | /// Pointer to function that can evaluate this binary operation. | 358 | /// Pointer to function that can evaluate this binary operation. | ||

250 | binop_eval_t EvalBinop; | 359 | binop_eval_t EvalBinop; | ||

251 | 360 | | |||

252 | public: | 361 | public: | ||

253 | FileCheckASTBinop(binop_eval_t EvalBinop, | 362 | FileCheckASTBinop(binop_eval_t EvalBinop, | ||

254 | std::shared_ptr<FileCheckExpressionAST> OperandLeft, | 363 | std::shared_ptr<FileCheckExpressionAST> OperandLeft, | ||

255 | std::shared_ptr<FileCheckExpressionAST> OperandRight) | 364 | std::shared_ptr<FileCheckExpressionAST> OperandRight) | ||

256 | : LeftOp(OperandLeft), RightOp(OperandRight), EvalBinop(EvalBinop) {} | 365 | : LeftOp(OperandLeft), RightOp(OperandRight), EvalBinop(EvalBinop) {} | ||

257 | 366 | | |||

258 | /// Evaluates the value of the binary operation represented by this AST, | 367 | /// Evaluates the value of the binary operation represented by this AST, | ||

259 | /// using EvalBinop on the result of recursively evaluating the operands. | 368 | /// using EvalBinop on the result of recursively evaluating the operands. | ||

260 | /// \returns an error if a numeric variable used is undefined, or the | 369 | /// \returns an error if a numeric variable used is undefined, or the | ||

261 | /// expression value otherwise. | 370 | /// expression value otherwise. | ||

262 | Expected<uint64_t> eval() const; | 371 | Expected<FileCheckExpressionValue> eval() const; | ||

263 | 372 | | |||

264 | /// \returns implicit format of this AST, FormatConflict if implicit formats | 373 | /// \returns implicit format of this AST, FormatConflict if implicit formats | ||

265 | /// of the AST's components conflict and Format none if the AST has no | 374 | /// of the AST's components conflict and Format none if the AST has no | ||

266 | /// implicit format (e.g. AST is made of a single literal). | 375 | /// implicit format (e.g. AST is made of a single literal). | ||

267 | FileCheckExpressionFormat getImplicitFormat() const; | 376 | FileCheckExpressionFormat getImplicitFormat() const; | ||

268 | }; | 377 | }; | ||

269 | 378 | | |||

270 | class FileCheckPatternContext; | 379 | class FileCheckPatternContext; | ||

▲ Show 20 Lines • Show All 566 Lines • Show Last 20 Lines |