diff options
Diffstat (limited to 'clang/lib/CIR/Dialect/IR/CIRAttrs.cpp')
-rw-r--r-- | clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 172 |
1 files changed, 168 insertions, 4 deletions
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 7d42da1..8e8f7d5 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -12,6 +12,24 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "mlir/IR/DialectImplementation.h" +#include "llvm/ADT/TypeSwitch.h" + +static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, + mlir::Type ty); +static mlir::ParseResult +parseFloatLiteral(mlir::AsmParser &parser, + mlir::FailureOr<llvm::APFloat> &value, + cir::CIRFPTypeInterface fpType); + +static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser, + mlir::IntegerAttr &value); + +static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value); + +#define GET_ATTRDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" + using namespace mlir; using namespace cir; @@ -21,12 +39,155 @@ using namespace cir; Attribute CIRDialect::parseAttribute(DialectAsmParser &parser, Type type) const { - // No attributes yet to parse - return Attribute{}; + llvm::SMLoc typeLoc = parser.getCurrentLocation(); + llvm::StringRef mnemonic; + Attribute genAttr; + OptionalParseResult parseResult = + generatedAttributeParser(parser, &mnemonic, type, genAttr); + if (parseResult.has_value()) + return genAttr; + parser.emitError(typeLoc, "unknown attribute in CIR dialect"); + return Attribute(); } void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { - // No attributes yet to print + if (failed(generatedAttributePrinter(attr, os))) + llvm_unreachable("unexpected CIR type kind"); +} + +//===----------------------------------------------------------------------===// +// ConstPtrAttr definitions +//===----------------------------------------------------------------------===// + +// TODO(CIR): Consider encoding the null value differently and use conditional +// assembly format instead of custom parsing/printing. +static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) { + + if (parser.parseOptionalKeyword("null").succeeded()) { + value = mlir::IntegerAttr::get( + mlir::IntegerType::get(parser.getContext(), 64), 0); + return success(); + } + + return parser.parseAttribute(value); +} + +static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { + if (!value.getInt()) + p << "null"; + else + p << value; +} + +//===----------------------------------------------------------------------===// +// IntAttr definitions +//===----------------------------------------------------------------------===// + +Attribute IntAttr::parse(AsmParser &parser, Type odsType) { + mlir::APInt apValue; + + if (!mlir::isa<IntType>(odsType)) + return {}; + auto type = mlir::cast<IntType>(odsType); + + // Consume the '<' symbol. + if (parser.parseLess()) + return {}; + + // Fetch arbitrary precision integer value. + if (type.isSigned()) { + int64_t value = 0; + if (parser.parseInteger(value)) { + parser.emitError(parser.getCurrentLocation(), "expected integer value"); + } else { + apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), + /*implicitTrunc=*/true); + if (apValue.getSExtValue() != value) + parser.emitError(parser.getCurrentLocation(), + "integer value too large for the given type"); + } + } else { + uint64_t value = 0; + if (parser.parseInteger(value)) { + parser.emitError(parser.getCurrentLocation(), "expected integer value"); + } else { + apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), + /*implicitTrunc=*/true); + if (apValue.getZExtValue() != value) + parser.emitError(parser.getCurrentLocation(), + "integer value too large for the given type"); + } + } + + // Consume the '>' symbol. + if (parser.parseGreater()) + return {}; + + return IntAttr::get(type, apValue); +} + +void IntAttr::print(AsmPrinter &printer) const { + auto type = mlir::cast<IntType>(getType()); + printer << '<'; + if (type.isSigned()) + printer << getSInt(); + else + printer << getUInt(); + printer << '>'; +} + +LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError, + Type type, APInt value) { + if (!mlir::isa<IntType>(type)) { + emitError() << "expected 'simple.int' type"; + return failure(); + } + + auto intType = mlir::cast<IntType>(type); + if (value.getBitWidth() != intType.getWidth()) { + emitError() << "type and value bitwidth mismatch: " << intType.getWidth() + << " != " << value.getBitWidth(); + return failure(); + } + + return success(); +} + +//===----------------------------------------------------------------------===// +// FPAttr definitions +//===----------------------------------------------------------------------===// + +static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) { + p << value; +} + +static ParseResult parseFloatLiteral(AsmParser &parser, + FailureOr<APFloat> &value, + CIRFPTypeInterface fpType) { + + APFloat parsedValue(0.0); + if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue)) + return failure(); + + value.emplace(parsedValue); + return success(); +} + +FPAttr FPAttr::getZero(Type type) { + return get(type, + APFloat::getZero( + mlir::cast<CIRFPTypeInterface>(type).getFloatSemantics())); +} + +LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError, + CIRFPTypeInterface fpType, APFloat value) { + if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) != + APFloat::SemanticsToEnum(value.getSemantics())) { + emitError() << "floating-point semantics mismatch"; + return failure(); + } + + return success(); } //===----------------------------------------------------------------------===// @@ -34,5 +195,8 @@ void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { //===----------------------------------------------------------------------===// void CIRDialect::registerAttributes() { - // No attributes yet to register + addAttributes< +#define GET_ATTRDEF_LIST +#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" + >(); } |