LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SMTInfoAttributes.cpp
Go to the documentation of this file.
1//===-- SMTInfoAttributes.cpp - SMT script metadata attributes --*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2026 Project LLZK
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
11
12#include "SMTInfoDetail.h"
13
15
16#include <mlir/IR/Diagnostics.h>
17#include <mlir/IR/DialectImplementation.h>
18#include <mlir/IR/OpImplementation.h>
19
20#include <llvm/ADT/StringExtras.h>
21#include <llvm/ADT/TypeSwitch.h>
22
23using namespace mlir;
24using namespace llzk::smt_info;
25
26#define GET_ATTRDEF_CLASSES
28
29namespace {
30
31bool isValidAtomChar(char ch) {
32 return llvm::isAlnum(ch) || ch == '_' || ch == '.' || ch == '$' || ch == '-' || ch == '!';
33}
34
35LogicalResult
36verifySymbol(function_ref<InFlightDiagnostic()> emitError, StringRef text, bool keyword) {
37 if (text.empty()) {
38 return emitError() << "symbol text must not be empty";
39 }
40 if (keyword) {
41 if (!text.starts_with(':')) {
42 return emitError() << "keyword must start with ':'";
43 }
44 text = text.drop_front();
45 } else if (text.starts_with(':')) {
46 return emitError() << "symbol must not start with ':'";
47 }
48 if (text.empty()) {
49 return emitError() << "keyword must contain characters after ':'";
50 }
51 for (char ch : text) {
52 if (!isValidAtomChar(ch)) {
53 return emitError() << "invalid SMT-LIB symbol character '" << ch << '\'';
54 }
55 }
56 return success();
57}
58
59} // namespace
60
61LogicalResult KeywordAttr::verify(function_ref<InFlightDiagnostic()> emitError, StringRef value) {
62 return verifySymbol(emitError, value, true);
63}
64
65Attribute KeywordAttr::parse(AsmParser &parser, Type) {
66 SMLoc loc = parser.getCurrentLocation();
67 StringRef value;
68 if (parser.parseLess() || parser.parseColon() || parser.parseKeyword(&value) ||
69 parser.parseGreater()) {
70 return {};
71 }
72 return parser.getChecked<KeywordAttr>(loc, parser.getContext(), (":" + value).str());
73}
74
75void KeywordAttr::print(AsmPrinter &printer) const { printer << '<' << getValue() << '>'; }
76
77LogicalResult SymbolAttr::verify(function_ref<InFlightDiagnostic()> emitError, StringRef value) {
78 return verifySymbol(emitError, value, false);
79}
80
81Attribute SymbolAttr::parse(AsmParser &parser, Type) {
82 SMLoc loc = parser.getCurrentLocation();
83 StringRef value;
84 if (parser.parseLess() || parser.parseKeyword(&value) || parser.parseGreater()) {
85 return {};
86 }
87 return parser.getChecked<SymbolAttr>(loc, parser.getContext(), value.str());
88}
89
90void SymbolAttr::print(AsmPrinter &printer) const { printer << '<' << getValue() << '>'; }
91
92Attribute llzk::smt_info::detail::getKeywordAttr(MLIRContext *context, StringRef value) {
93 return KeywordAttr::get(context, value);
94}
95
96Attribute llzk::smt_info::detail::getSymbolAttr(MLIRContext *context, StringRef value) {
97 return SymbolAttr::get(context, value);
98}
99
101 function_ref<InFlightDiagnostic()> emitError, StringRef value
102) {
103 return verifySymbol(emitError, value, true);
104}
105
107 // clang-format off
108 addAttributes<
109 #define GET_ATTRDEF_LIST
111 >();
112 // clang-format on
113}
mlir::Attribute getSymbolAttr(mlir::MLIRContext *context, llvm::StringRef value)
Creates a symbol attribute without exposing generated attribute storage to operation implementation f...
mlir::Attribute getKeywordAttr(mlir::MLIRContext *context, llvm::StringRef value)
Creates a keyword attribute without exposing generated attribute storage to operation implementation ...
mlir::LogicalResult verifyKeyword(llvm::function_ref< mlir::InFlightDiagnostic()> emitError, llvm::StringRef value)
Verifies that value is a valid SMT-LIB keyword and reports failures through emitError.