@@ -65,11 +65,12 @@ class Property<string storageTypeParam = "", string desc = ""> {
6565 return convertFromAttribute($_storage, $_attr, $_diag);
6666 }];
6767
68- // The verification predicate for this property. Defaults to And<[]> ,
69- // which is trivially true, since properties are always their expected type.
68+ // The verification predicate for this property. Defaults to the true predicate ,
69+ // since properties are always their expected type.
7070 // Within the predicate, `$_self` is an instance of the **interface**
71- // type of the property.
72- Pred predicate = ?;
71+ // type of the property. Setting this field to ? will also result in a
72+ // true predicate but is not recommended, as it breaks composability.
73+ Pred predicate = TruePred;
7374
7475 // The call expression to hash the property.
7576 //
@@ -365,9 +366,12 @@ class DefaultValuedProperty<Property p, string default = "", string storageDefau
365366 let writeToMlirBytecode = p.writeToMlirBytecode;
366367}
367368
369+ /// Apply the predicate `pred` to the property `p`, ANDing it with any
370+ /// predicates it may already have. If `newSummary` is provided, replace the
371+ /// summary of `p` with `newSummary`.
368372class ConfinedProperty<Property p, Pred pred, string newSummary = "">
369373 : Property<p.storageType, !if(!empty(newSummary), p.summary, newSummary)> {
370- let predicate = !if(!initialized (p.predicate), And<[p.predicate, pred]>, pred);
374+ let predicate = !if(!ne (p.predicate, TruePred ), And<[p.predicate, pred]>, pred);
371375 let baseProperty = p;
372376 // Keep up to date with `Property` above.
373377 let description = p.description;
@@ -409,17 +413,15 @@ class _makePropStorage<Property prop, string name> {
409413/// }
410414///
411415/// and then appends `prefix` and `suffix`.
412- class _makeChildWrapperPred<string prefix, Property wrappedProp, string suffix > {
416+ class _makeStoragedWrapperPred< Property wrappedProp> {
413417 Pred ret =
414- !if(!initialized(wrappedProp.predicate),
415- Concat<
416- prefix # "[]("
417- # "const " # wrappedProp.storageType # "& baseStore) -> bool { return []("
418- # wrappedProp.interfaceType # " baseIface) -> bool { return (",
419- SubstLeaves<"$_self", "baseIface", wrappedProp.predicate>,
420- "); }(" # !subst("$_storage", "baseStore", wrappedProp.convertFromStorage)
421- # "); }" # suffix
422- >, ?);
418+ Concat<
419+ "[](" # "const " # wrappedProp.storageType
420+ # "& baseStore) -> bool { return []("
421+ # wrappedProp.interfaceType # " baseIface) -> bool { return (",
422+ SubstLeaves<"$_self", "baseIface", wrappedProp.predicate>,
423+ "); }(" # !subst("$_storage", "baseStore", wrappedProp.convertFromStorage)
424+ # "); }">;
423425}
424426
425427/// The generic class for arrays of some other property, which is stored as a
@@ -462,7 +464,9 @@ class ArrayProperty<Property elem = Property<>, string newSummary = ""> :
462464 return ::mlir::ArrayAttr::get($_ctxt, elems);
463465 }];
464466
465- let predicate = _makeChildWrapperPred<"::llvm::all_of($_self, ", elem, ")">.ret;
467+ let predicate = !if(!eq(elem.predicate, TruePred),
468+ TruePred,
469+ Concat<"::llvm::all_of($_self, ", _makeStoragedWrapperPred<elem>.ret, ")">);
466470
467471 defvar theParserBegin = [{
468472 auto& storage = $_storage;
@@ -633,10 +637,10 @@ class OptionalProperty<Property p, bit canDelegateParsing = 1>
633637 return ::mlir::ArrayAttr::get($_ctxt, {attr});
634638 }];
635639
636- let predicate = !if(!initialized (p.predicate),
640+ let predicate = !if(!ne (p.predicate, TruePred ),
637641 Or<[CPred<"!$_self.has_value()">,
638642 SubstLeaves<"$_self", "(*($_self))", p.predicate>]>,
639- ? );
643+ TruePred );
640644
641645 defvar delegatedParserBegin = [{
642646 if (::mlir::succeeded($_parser.parseOptionalKeyword("none"))) {
0 commit comments