-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[AsmParser][NFCI] Restructure DiagnosticPredicate #126653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This restructures the DiagnosticPredicate type to more closely match how neatly ParseStatus is defined. The DiagnosticPredicateTy enum is moved inside the class, but is exposed with constexpr/using so that references don't have to be so long. The main user of this code is AArch64, which I have also updated to use the new structure of the code.
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-aarch64 Author: Sam Elliott (lenary) ChangesThis restructures the DiagnosticPredicate type to more closely match how neatly ParseStatus is defined. The DiagnosticPredicateTy enum is moved inside the class, but is exposed with constexpr/using so that references don't have to be so long. The main user of this code is AArch64, which I have also updated to use the new structure of the code. Full diff: https://github.com/llvm/llvm-project/pull/126653.diff 2 Files Affected:
diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index 4c88448e6a1285a..c856d9f68b4822c 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -167,12 +167,6 @@ class ParseStatus {
}
};
-enum class DiagnosticPredicateTy {
- Match,
- NearMatch,
- NoMatch,
-};
-
// When an operand is parsed, the assembler will try to iterate through a set of
// possible operand classes that the operand might match and call the
// corresponding PredicateMethod to determine that.
@@ -199,20 +193,35 @@ enum class DiagnosticPredicateTy {
// below which collects *all* possible diagnostics. This alternative
// is optional and fully backward compatible with existing
// PredicateMethods that return a 'bool' (match or no match).
-struct DiagnosticPredicate {
- DiagnosticPredicateTy Type;
+class DiagnosticPredicate {
+ enum class PredicateTy {
+ Match, // Matches
+ NearMatch, // Close Match: use Specific Diagnostic
+ NoMatch, // No Match: use `InvalidOperand`
+ } Predicate;
+
+public:
+#if __cplusplus >= 202002L
+ using enum PredicateTy;
+#else
+ static constexpr PredicateTy Match = PredicateTy::Match;
+ static constexpr PredicateTy NearMatch = PredicateTy::NearMatch;
+ static constexpr PredicateTy NoMatch = PredicateTy::NoMatch;
+#endif
+
+ constexpr DiagnosticPredicate(PredicateTy T) : Predicate(T) {}
- explicit DiagnosticPredicate(bool Match)
- : Type(Match ? DiagnosticPredicateTy::Match
- : DiagnosticPredicateTy::NearMatch) {}
- DiagnosticPredicate(DiagnosticPredicateTy T) : Type(T) {}
- DiagnosticPredicate(const DiagnosticPredicate &) = default;
DiagnosticPredicate& operator=(const DiagnosticPredicate &) = default;
+ DiagnosticPredicate(const DiagnosticPredicate &) = default;
+
+ explicit constexpr DiagnosticPredicate(bool Matches)
+ : Predicate(Matches ? Match : NearMatch) {}
+
+ operator bool() const { return Predicate == Match; }
- operator bool() const { return Type == DiagnosticPredicateTy::Match; }
- bool isMatch() const { return Type == DiagnosticPredicateTy::Match; }
- bool isNearMatch() const { return Type == DiagnosticPredicateTy::NearMatch; }
- bool isNoMatch() const { return Type == DiagnosticPredicateTy::NoMatch; }
+ constexpr bool isMatch() const { return Predicate == Match; }
+ constexpr bool isNearMatch() const { return Predicate == NearMatch; }
+ constexpr bool isNoMatch() const { return Predicate == NoMatch; }
};
// When matching of an assembly instruction fails, there may be multiple
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 335b46b76688fa4..38963810e28d637 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -824,7 +824,7 @@ class AArch64Operand : public MCParsedAsmOperand {
DiagnosticPredicate isUImmScaled() const {
if (IsRange && isImmRange() &&
(getLastImmVal() != getFirstImmVal() + Offset))
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
return isImmScaled<Bits, Scale, IsRange>(false);
}
@@ -833,7 +833,7 @@ class AArch64Operand : public MCParsedAsmOperand {
DiagnosticPredicate isImmScaled(bool Signed) const {
if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
(isImmRange() && !IsRange))
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
int64_t Val;
if (isImmRange())
@@ -841,7 +841,7 @@ class AArch64Operand : public MCParsedAsmOperand {
else {
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
Val = MCE->getValue();
}
@@ -856,33 +856,33 @@ class AArch64Operand : public MCParsedAsmOperand {
}
if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
DiagnosticPredicate isSVEPattern() const {
if (!isImm())
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
auto *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
int64_t Val = MCE->getValue();
if (Val >= 0 && Val < 32)
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NearMatch;
}
DiagnosticPredicate isSVEVecLenSpecifier() const {
if (!isImm())
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
auto *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
int64_t Val = MCE->getValue();
if (Val >= 0 && Val <= 1)
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NearMatch;
}
bool isSymbolicUImm12Offset(const MCExpr *Expr) const {
@@ -1057,7 +1057,7 @@ class AArch64Operand : public MCParsedAsmOperand {
template <typename T>
DiagnosticPredicate isSVECpyImm() const {
if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
std::is_same<int8_t, T>::value;
@@ -1065,9 +1065,9 @@ class AArch64Operand : public MCParsedAsmOperand {
if (!(IsByte && ShiftedImm->second) &&
AArch64_AM::isSVECpyImm<T>(uint64_t(ShiftedImm->first)
<< ShiftedImm->second))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
// Unsigned value in the range 0 to 255. For element widths of
@@ -1075,7 +1075,7 @@ class AArch64Operand : public MCParsedAsmOperand {
// range 0 to 65280.
template <typename T> DiagnosticPredicate isSVEAddSubImm() const {
if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
std::is_same<int8_t, T>::value;
@@ -1083,15 +1083,15 @@ class AArch64Operand : public MCParsedAsmOperand {
if (!(IsByte && ShiftedImm->second) &&
AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
<< ShiftedImm->second))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <typename T> DiagnosticPredicate isSVEPreferredLogicalImm() const {
if (isLogicalImm<T>() && !isSVECpyImm<T>())
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NoMatch;
}
bool isCondCode() const { return Kind == k_CondCode; }
@@ -1319,48 +1319,48 @@ class AArch64Operand : public MCParsedAsmOperand {
template <int ElementWidth, unsigned Class>
DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const {
if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (isSVEVectorReg<Class>() && (Reg.ElementWidth == ElementWidth))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <int ElementWidth, unsigned Class>
DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth() const {
if (Kind != k_Register || (Reg.Kind != RegKind::SVEPredicateAsCounter &&
Reg.Kind != RegKind::SVEPredicateVector))
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if ((isSVEPredicateAsCounterReg<Class>() ||
isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
Reg.ElementWidth == ElementWidth)
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <int ElementWidth, unsigned Class>
DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth() const {
if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateAsCounter)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (isSVEPredicateAsCounterReg<Class>() && (Reg.ElementWidth == ElementWidth))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <int ElementWidth, unsigned Class>
DiagnosticPredicate isSVEDataVectorRegOfWidth() const {
if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (isSVEVectorReg<Class>() && Reg.ElementWidth == ElementWidth)
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <int ElementWidth, unsigned Class,
@@ -1369,7 +1369,7 @@ class AArch64Operand : public MCParsedAsmOperand {
DiagnosticPredicate isSVEDataVectorRegWithShiftExtend() const {
auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
if (!VectorMatch.isMatch())
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
// Give a more specific diagnostic when the user has explicitly typed in
// a shift-amount that does not match what is expected, but for which
@@ -1378,12 +1378,12 @@ class AArch64Operand : public MCParsedAsmOperand {
if (!MatchShift && (ShiftExtendTy == AArch64_AM::UXTW ||
ShiftExtendTy == AArch64_AM::SXTW) &&
!ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (MatchShift && ShiftExtendTy == getShiftExtendType())
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
bool isGPR32as64() const {
@@ -1420,15 +1420,17 @@ class AArch64Operand : public MCParsedAsmOperand {
template<int64_t Angle, int64_t Remainder>
DiagnosticPredicate isComplexRotation() const {
- if (!isImm()) return DiagnosticPredicateTy::NoMatch;
+ if (!isImm())
+ return DiagnosticPredicate::NoMatch;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE) return DiagnosticPredicateTy::NoMatch;
+ if (!CE)
+ return DiagnosticPredicate::NoMatch;
uint64_t Value = CE->getValue();
if (Value % Angle == Remainder && Value <= 270)
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NearMatch;
}
template <unsigned RegClassID> bool isGPR64() const {
@@ -1439,12 +1441,12 @@ class AArch64Operand : public MCParsedAsmOperand {
template <unsigned RegClassID, int ExtWidth>
DiagnosticPredicate isGPR64WithShiftExtend() const {
if (Kind != k_Register || Reg.Kind != RegKind::Scalar)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (isGPR64<RegClassID>() && getShiftExtendType() == AArch64_AM::LSL &&
getShiftExtendAmount() == Log2_32(ExtWidth / 8))
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NearMatch;
}
/// Is this a vector list with the type implicit (presumably attached to the
@@ -1479,10 +1481,10 @@ class AArch64Operand : public MCParsedAsmOperand {
bool Res =
isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
if (!Res)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (!AArch64MCRegisterClasses[RegClass].contains(VectorList.RegNum))
- return DiagnosticPredicateTy::NearMatch;
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::NearMatch;
+ return DiagnosticPredicate::Match;
}
template <RegKind VectorKind, unsigned NumRegs, unsigned Stride,
@@ -1491,21 +1493,21 @@ class AArch64Operand : public MCParsedAsmOperand {
bool Res = isTypedVectorList<VectorKind, NumRegs, /*NumElements*/ 0,
ElementWidth, Stride>();
if (!Res)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
((VectorList.RegNum >= AArch64::Z16) &&
(VectorList.RegNum < (AArch64::Z16 + Stride))))
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NoMatch;
}
template <int Min, int Max>
DiagnosticPredicate isVectorIndex() const {
if (Kind != k_VectorIndex)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
- return DiagnosticPredicateTy::Match;
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::Match;
+ return DiagnosticPredicate::NearMatch;
}
bool isToken() const override { return Kind == k_Token; }
@@ -1531,7 +1533,7 @@ class AArch64Operand : public MCParsedAsmOperand {
template <unsigned ImmEnum> DiagnosticPredicate isExactFPImm() const {
if (Kind != k_FPImm)
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (getFPImmIsExact()) {
// Lookup the immediate from table of supported immediates.
@@ -1546,19 +1548,19 @@ class AArch64Operand : public MCParsedAsmOperand {
llvm_unreachable("FP immediate is not exact");
if (getFPImm().bitwiseIsEqual(RealVal))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
}
- return DiagnosticPredicateTy::NearMatch;
+ return DiagnosticPredicate::NearMatch;
}
template <unsigned ImmA, unsigned ImmB>
DiagnosticPredicate isExactFPImm() const {
- DiagnosticPredicate Res = DiagnosticPredicateTy::NoMatch;
+ DiagnosticPredicate Res = DiagnosticPredicate::NoMatch;
if ((Res = isExactFPImm<ImmA>()))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
if ((Res = isExactFPImm<ImmB>()))
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::Match;
return Res;
}
@@ -1741,12 +1743,12 @@ class AArch64Operand : public MCParsedAsmOperand {
template <MatrixKind Kind, unsigned EltSize, unsigned RegClass>
DiagnosticPredicate isMatrixRegOperand() const {
if (!isMatrix())
- return DiagnosticPredicateTy::NoMatch;
+ return DiagnosticPredicate::NoMatch;
if (getMatrixKind() != Kind ||
!AArch64MCRegisterClasses[RegClass].contains(getMatrixReg()) ||
EltSize != getMatrixElementWidth())
- return DiagnosticPredicateTy::NearMatch;
- return DiagnosticPredicateTy::Match;
+ return DiagnosticPredicate::NearMatch;
+ return DiagnosticPredicate::Match;
}
bool isPAuthPCRelLabel16Operand() const {
|
The fixup contains a change to a comment to make it accurate with the existing behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
✅ With the latest revision this PR passed the C/C++ code formatter. |
This restructures the DiagnosticPredicate type to more closely match how neatly ParseStatus is defined. The DiagnosticPredicateTy enum is moved inside the class, and the boolean conversions are made explicit. The main user of this code is AArch64, which I have also updated to use the new structure of the code.
This restructures the DiagnosticPredicate type to more closely match how neatly ParseStatus is defined. The DiagnosticPredicateTy enum is moved inside the class, and the boolean conversions are made explicit. The main user of this code is AArch64, which I have also updated to use the new structure of the code.
This restructures the DiagnosticPredicate type to more closely match how neatly ParseStatus is defined. The DiagnosticPredicateTy enum is moved inside the class, but is exposed with constexpr/using so that references don't have to be so long.
The main user of this code is AArch64, which I have also updated to use the new structure of the code.