File indexing completed on 2026-05-10 08:36:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_COMPARISONCATEGORIES_H
0015 #define LLVM_CLANG_AST_COMPARISONCATEGORIES_H
0016
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/APSInt.h"
0019 #include "llvm/ADT/DenseMap.h"
0020 #include <array>
0021 #include <cassert>
0022 #include <optional>
0023 #include <vector>
0024
0025 namespace llvm {
0026 class StringRef;
0027 class APSInt;
0028 }
0029
0030 namespace clang {
0031
0032 class ASTContext;
0033 class VarDecl;
0034 class CXXRecordDecl;
0035 class Sema;
0036 class QualType;
0037 class NamespaceDecl;
0038
0039
0040
0041
0042
0043
0044 enum class ComparisonCategoryType : unsigned char {
0045 PartialOrdering,
0046 WeakOrdering,
0047 StrongOrdering,
0048 First = PartialOrdering,
0049 Last = StrongOrdering
0050 };
0051
0052
0053
0054 inline ComparisonCategoryType commonComparisonType(ComparisonCategoryType A,
0055 ComparisonCategoryType B) {
0056 return A < B ? A : B;
0057 }
0058
0059
0060
0061 std::optional<ComparisonCategoryType>
0062 getComparisonCategoryForBuiltinCmp(QualType T);
0063
0064
0065
0066
0067 enum class ComparisonCategoryResult : unsigned char {
0068 Equal,
0069 Equivalent,
0070 Less,
0071 Greater,
0072 Unordered,
0073 Last = Unordered
0074 };
0075
0076 class ComparisonCategoryInfo {
0077 friend class ComparisonCategories;
0078 friend class Sema;
0079
0080 public:
0081 ComparisonCategoryInfo(const ASTContext &Ctx, const CXXRecordDecl *RD,
0082 ComparisonCategoryType Kind)
0083 : Ctx(Ctx), Record(RD), Kind(Kind) {}
0084
0085 struct ValueInfo {
0086 ComparisonCategoryResult Kind;
0087 VarDecl *VD;
0088
0089 ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
0090 : Kind(Kind), VD(VD) {}
0091
0092
0093
0094 bool hasValidIntValue() const;
0095
0096
0097
0098 llvm::APSInt getIntValue() const;
0099 };
0100 private:
0101 const ASTContext &Ctx;
0102
0103
0104
0105 mutable llvm::SmallVector<
0106 ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1>
0107 Objects;
0108
0109
0110
0111
0112
0113
0114 ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const;
0115
0116 public:
0117
0118
0119 const CXXRecordDecl *Record = nullptr;
0120
0121
0122 ComparisonCategoryType Kind;
0123
0124 public:
0125 QualType getType() const;
0126
0127 const ValueInfo *getValueInfo(ComparisonCategoryResult ValueKind) const {
0128 ValueInfo *Info = lookupValueInfo(ValueKind);
0129 assert(Info &&
0130 "comparison category does not contain the specified result kind");
0131 assert(Info->hasValidIntValue() &&
0132 "couldn't determine the integer constant for this value");
0133 return Info;
0134 }
0135
0136
0137
0138 bool isStrong() const {
0139 using CCK = ComparisonCategoryType;
0140 return Kind == CCK::StrongOrdering;
0141 }
0142
0143
0144 bool isPartial() const {
0145 using CCK = ComparisonCategoryType;
0146 return Kind == CCK::PartialOrdering;
0147 }
0148
0149
0150
0151
0152 ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
0153 using CCR = ComparisonCategoryResult;
0154 if (!isStrong() && Res == CCR::Equal)
0155 return CCR::Equivalent;
0156 return Res;
0157 }
0158
0159 const ValueInfo *getEqualOrEquiv() const {
0160 return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal));
0161 }
0162 const ValueInfo *getLess() const {
0163 return getValueInfo(ComparisonCategoryResult::Less);
0164 }
0165 const ValueInfo *getGreater() const {
0166 return getValueInfo(ComparisonCategoryResult::Greater);
0167 }
0168 const ValueInfo *getUnordered() const {
0169 assert(isPartial());
0170 return getValueInfo(ComparisonCategoryResult::Unordered);
0171 }
0172 };
0173
0174 class ComparisonCategories {
0175 public:
0176 static StringRef getCategoryString(ComparisonCategoryType Kind);
0177 static StringRef getResultString(ComparisonCategoryResult Kind);
0178
0179
0180
0181 static std::vector<ComparisonCategoryResult>
0182 getPossibleResultsForType(ComparisonCategoryType Type);
0183
0184
0185
0186 const ComparisonCategoryInfo &getInfo(ComparisonCategoryType Kind) const {
0187 const ComparisonCategoryInfo *Result = lookupInfo(Kind);
0188 assert(Result != nullptr &&
0189 "information for specified comparison category has not been built");
0190 return *Result;
0191 }
0192
0193
0194
0195
0196
0197
0198 const ComparisonCategoryInfo &getInfoForType(QualType Ty) const;
0199
0200 public:
0201
0202
0203
0204
0205 const ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) const;
0206
0207 ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) {
0208 const auto &This = *this;
0209 return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
0210 }
0211
0212 const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
0213
0214 private:
0215 friend class ASTContext;
0216
0217 explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {}
0218
0219 const ASTContext &Ctx;
0220
0221
0222
0223 mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data;
0224 mutable NamespaceDecl *StdNS = nullptr;
0225 };
0226
0227 }
0228
0229 #endif