aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/Dialect/IR/CIRAttrs.cpp')
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRAttrs.cpp172
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"
+ >();
}