|
26 | 26 | #include "mlir/Support/LLVM.h" |
27 | 27 | #include "mlir/Support/LogicalResult.h" |
28 | 28 |
|
| 29 | +#include "clang/CIR/Interfaces/CIRTypeInterfaces.h" |
29 | 30 | #include "llvm/ADT/STLExtras.h" |
30 | 31 | #include "llvm/ADT/TypeSwitch.h" |
31 | 32 |
|
32 | 33 | // ClangIR holds back AST references when available. |
33 | 34 | #include "clang/AST/Decl.h" |
34 | 35 | #include "clang/AST/DeclCXX.h" |
35 | 36 | #include "clang/AST/ExprCXX.h" |
| 37 | +#include "llvm/Support/ErrorHandling.h" |
| 38 | +#include "llvm/Support/SMLoc.h" |
| 39 | + |
| 40 | +//===-----------------------------------------------------------------===// |
| 41 | +// RecordMembers |
| 42 | +//===-----------------------------------------------------------------===// |
36 | 43 |
|
37 | 44 | static void printRecordMembers(mlir::AsmPrinter &p, mlir::ArrayAttr members); |
38 | 45 | static mlir::ParseResult parseRecordMembers(::mlir::AsmParser &parser, |
39 | 46 | mlir::ArrayAttr &members); |
40 | 47 |
|
| 48 | +//===-----------------------------------------------------------------===// |
| 49 | +// IntLiteral |
| 50 | +//===-----------------------------------------------------------------===// |
| 51 | + |
| 52 | +static void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, |
| 53 | + cir::IntTypeInterface ty); |
| 54 | + |
| 55 | +static mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, |
| 56 | + llvm::APInt &value, |
| 57 | + cir::IntTypeInterface ty); |
| 58 | + |
| 59 | +//===-----------------------------------------------------------------===// |
| 60 | +// FloatLiteral |
| 61 | +//===-----------------------------------------------------------------===// |
| 62 | + |
41 | 63 | static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, |
42 | 64 | mlir::Type ty); |
43 | 65 | static mlir::ParseResult |
@@ -204,65 +226,52 @@ static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { |
204 | 226 | // IntAttr definitions |
205 | 227 | //===----------------------------------------------------------------------===// |
206 | 228 |
|
207 | | -Attribute IntAttr::parse(AsmParser &parser, Type odsType) { |
208 | | - mlir::APInt APValue; |
| 229 | +template <typename IntT> |
| 230 | +static bool isTooLargeForType(const mlir::APInt &v, IntT expectedValue) { |
| 231 | + if constexpr (std::is_signed_v<IntT>) { |
| 232 | + return v.getSExtValue() != expectedValue; |
| 233 | + } else { |
| 234 | + return v.getZExtValue() != expectedValue; |
| 235 | + } |
| 236 | +} |
209 | 237 |
|
210 | | - if (!mlir::isa<IntType>(odsType)) |
211 | | - return {}; |
212 | | - auto type = mlir::cast<IntType>(odsType); |
| 238 | +template <typename IntT> |
| 239 | +static ParseResult parseIntLiteralImpl(mlir::AsmParser &p, llvm::APInt &value, |
| 240 | + cir::IntTypeInterface ty) { |
| 241 | + IntT ivalue; |
| 242 | + const bool isSigned = ty.isSigned(); |
| 243 | + if (p.parseInteger(ivalue)) |
| 244 | + return p.emitError(p.getCurrentLocation(), "expected integer value"); |
213 | 245 |
|
214 | | - // Consume the '<' symbol. |
215 | | - if (parser.parseLess()) |
216 | | - return {}; |
| 246 | + value = mlir::APInt(ty.getWidth(), ivalue, isSigned, /*implicitTrunc=*/true); |
| 247 | + if (isTooLargeForType(value, ivalue)) |
217 | 248 |
|
218 | | - // Fetch arbitrary precision integer value. |
219 | | - if (type.isSigned()) { |
220 | | - int64_t value; |
221 | | - if (parser.parseInteger(value)) |
222 | | - parser.emitError(parser.getCurrentLocation(), "expected integer value"); |
223 | | - APValue = mlir::APInt(type.getWidth(), value, type.isSigned(), |
224 | | - /*implicitTrunc=*/true); |
225 | | - if (APValue.getSExtValue() != value) |
226 | | - parser.emitError(parser.getCurrentLocation(), |
| 249 | + return p.emitError(p.getCurrentLocation(), |
227 | 250 | "integer value too large for the given type"); |
228 | | - } else { |
229 | | - uint64_t value; |
230 | | - if (parser.parseInteger(value)) |
231 | | - parser.emitError(parser.getCurrentLocation(), "expected integer value"); |
232 | | - APValue = mlir::APInt(type.getWidth(), value, type.isSigned(), |
233 | | - /*implicitTrunc=*/true); |
234 | | - if (APValue.getZExtValue() != value) |
235 | | - parser.emitError(parser.getCurrentLocation(), |
236 | | - "integer value too large for the given type"); |
237 | | - } |
238 | 251 |
|
239 | | - // Consume the '>' symbol. |
240 | | - if (parser.parseGreater()) |
241 | | - return {}; |
| 252 | + return success(); |
| 253 | +} |
242 | 254 |
|
243 | | - return IntAttr::get(type, APValue); |
| 255 | +mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, llvm::APInt &value, |
| 256 | + cir::IntTypeInterface ty) { |
| 257 | + if (ty.isSigned()) |
| 258 | + return parseIntLiteralImpl<int64_t>(parser, value, ty); |
| 259 | + return parseIntLiteralImpl<uint64_t>(parser, value, ty); |
244 | 260 | } |
245 | 261 |
|
246 | | -void IntAttr::print(AsmPrinter &printer) const { |
247 | | - auto type = mlir::cast<IntType>(getType()); |
248 | | - printer << '<'; |
249 | | - if (type.isSigned()) |
250 | | - printer << getSInt(); |
| 262 | +void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, |
| 263 | + cir::IntTypeInterface ty) { |
| 264 | + if (ty.isSigned()) |
| 265 | + p << value.getSExtValue(); |
251 | 266 | else |
252 | | - printer << getUInt(); |
253 | | - printer << '>'; |
| 267 | + p << value.getZExtValue(); |
254 | 268 | } |
255 | 269 |
|
256 | 270 | LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError, |
257 | | - Type type, APInt value) { |
258 | | - if (!mlir::isa<IntType>(type)) |
259 | | - return emitError() << "expected 'simple.int' type"; |
260 | | - |
261 | | - auto intType = mlir::cast<IntType>(type); |
262 | | - if (value.getBitWidth() != intType.getWidth()) |
| 271 | + cir::IntTypeInterface type, llvm::APInt value) { |
| 272 | + if (value.getBitWidth() != type.getWidth()) |
263 | 273 | return emitError() << "type and value bitwidth mismatch: " |
264 | | - << intType.getWidth() << " != " << value.getBitWidth(); |
265 | | - |
| 274 | + << type.getWidth() << " != " << value.getBitWidth(); |
266 | 275 | return success(); |
267 | 276 | } |
268 | 277 |
|
@@ -481,8 +490,8 @@ LogicalResult |
481 | 490 | GlobalAnnotationValuesAttr::verify(function_ref<InFlightDiagnostic()> emitError, |
482 | 491 | mlir::ArrayAttr annotations) { |
483 | 492 | if (annotations.empty()) |
484 | | - return emitError() |
485 | | - << "GlobalAnnotationValuesAttr should at least have one annotation"; |
| 493 | + return emitError() << "GlobalAnnotationValuesAttr should at least have " |
| 494 | + "one annotation"; |
486 | 495 |
|
487 | 496 | for (auto &entry : annotations) { |
488 | 497 | auto annoEntry = ::mlir::dyn_cast<mlir::ArrayAttr>(entry); |
|
0 commit comments