1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_AST_COMPARISONCATEGORIES_H |
15 | #define LLVM_CLANG_AST_COMPARISONCATEGORIES_H |
16 | |
17 | #include "clang/Basic/LLVM.h" |
18 | #include "llvm/ADT/APSInt.h" |
19 | #include "llvm/ADT/DenseMap.h" |
20 | #include <array> |
21 | #include <cassert> |
22 | |
23 | namespace llvm { |
24 | class StringRef; |
25 | class APSInt; |
26 | } |
27 | |
28 | namespace clang { |
29 | |
30 | class ASTContext; |
31 | class VarDecl; |
32 | class CXXRecordDecl; |
33 | class Sema; |
34 | class QualType; |
35 | class NamespaceDecl; |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | enum class ComparisonCategoryType : unsigned char { |
44 | WeakEquality, |
45 | StrongEquality, |
46 | PartialOrdering, |
47 | WeakOrdering, |
48 | StrongOrdering, |
49 | First = WeakEquality, |
50 | Last = StrongOrdering |
51 | }; |
52 | |
53 | |
54 | |
55 | |
56 | enum class ComparisonCategoryResult : unsigned char { |
57 | Equal, |
58 | Equivalent, |
59 | Nonequivalent, |
60 | Nonequal, |
61 | Less, |
62 | Greater, |
63 | Unordered, |
64 | Last = Unordered |
65 | }; |
66 | |
67 | class ComparisonCategoryInfo { |
68 | friend class ComparisonCategories; |
69 | friend class Sema; |
70 | |
71 | public: |
72 | ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD, |
73 | ComparisonCategoryType Kind) |
74 | : Ctx(Ctx), Record(RD), Kind(Kind) {} |
75 | |
76 | struct ValueInfo { |
77 | ComparisonCategoryResult Kind; |
78 | VarDecl *VD; |
79 | |
80 | ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD) |
81 | : Kind(Kind), VD(VD) {} |
82 | |
83 | |
84 | |
85 | bool hasValidIntValue() const; |
86 | |
87 | |
88 | |
89 | llvm::APSInt getIntValue() const; |
90 | }; |
91 | private: |
92 | const ASTContext &Ctx; |
93 | |
94 | |
95 | |
96 | mutable llvm::SmallVector< |
97 | ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1> |
98 | Objects; |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const; |
106 | |
107 | public: |
108 | |
109 | |
110 | |
111 | CXXRecordDecl *Record = nullptr; |
112 | |
113 | |
114 | ComparisonCategoryType Kind; |
115 | |
116 | public: |
117 | QualType getType() const; |
118 | |
119 | const ValueInfo *getValueInfo(ComparisonCategoryResult ValueKind) const { |
120 | ValueInfo *Info = lookupValueInfo(ValueKind); |
121 | (0) . __assert_fail ("Info && \"comparison category does not contain the specified result kind\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 122, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Info && |
122 | (0) . __assert_fail ("Info && \"comparison category does not contain the specified result kind\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 122, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "comparison category does not contain the specified result kind"); |
123 | (0) . __assert_fail ("Info->hasValidIntValue() && \"couldn't determine the integer constant for this value\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 124, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Info->hasValidIntValue() && |
124 | (0) . __assert_fail ("Info->hasValidIntValue() && \"couldn't determine the integer constant for this value\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 124, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "couldn't determine the integer constant for this value"); |
125 | return Info; |
126 | } |
127 | |
128 | |
129 | bool isEquality() const { return !isOrdered(); } |
130 | |
131 | |
132 | bool isOrdered() const { |
133 | using CCK = ComparisonCategoryType; |
134 | return Kind == CCK::PartialOrdering || Kind == CCK::WeakOrdering || |
135 | Kind == CCK::StrongOrdering; |
136 | } |
137 | |
138 | |
139 | |
140 | bool isStrong() const { |
141 | using CCK = ComparisonCategoryType; |
142 | return Kind == CCK::StrongEquality || Kind == CCK::StrongOrdering; |
143 | } |
144 | |
145 | |
146 | bool isPartial() const { |
147 | using CCK = ComparisonCategoryType; |
148 | return Kind == CCK::PartialOrdering; |
149 | } |
150 | |
151 | |
152 | |
153 | |
154 | ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const { |
155 | using CCR = ComparisonCategoryResult; |
156 | if (!isStrong()) { |
157 | if (Res == CCR::Equal) |
158 | return CCR::Equivalent; |
159 | if (Res == CCR::Nonequal) |
160 | return CCR::Nonequivalent; |
161 | } |
162 | return Res; |
163 | } |
164 | |
165 | const ValueInfo *getEqualOrEquiv() const { |
166 | return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal)); |
167 | } |
168 | const ValueInfo *getNonequalOrNonequiv() const { |
169 | assert(isEquality()); |
170 | return getValueInfo(makeWeakResult(ComparisonCategoryResult::Nonequal)); |
171 | } |
172 | const ValueInfo *getLess() const { |
173 | assert(isOrdered()); |
174 | return getValueInfo(ComparisonCategoryResult::Less); |
175 | } |
176 | const ValueInfo *getGreater() const { |
177 | assert(isOrdered()); |
178 | return getValueInfo(ComparisonCategoryResult::Greater); |
179 | } |
180 | const ValueInfo *getUnordered() const { |
181 | assert(isPartial()); |
182 | return getValueInfo(ComparisonCategoryResult::Unordered); |
183 | } |
184 | }; |
185 | |
186 | class ComparisonCategories { |
187 | public: |
188 | static StringRef getCategoryString(ComparisonCategoryType Kind); |
189 | static StringRef getResultString(ComparisonCategoryResult Kind); |
190 | |
191 | |
192 | |
193 | static std::vector<ComparisonCategoryResult> |
194 | getPossibleResultsForType(ComparisonCategoryType Type); |
195 | |
196 | |
197 | |
198 | const ComparisonCategoryInfo &getInfo(ComparisonCategoryType Kind) const { |
199 | const ComparisonCategoryInfo *Result = lookupInfo(Kind); |
200 | (0) . __assert_fail ("Result != nullptr && \"information for specified comparison category has not been built\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 201, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Result != nullptr && |
201 | (0) . __assert_fail ("Result != nullptr && \"information for specified comparison category has not been built\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/ComparisonCategories.h", 201, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "information for specified comparison category has not been built"); |
202 | return *Result; |
203 | } |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | const ComparisonCategoryInfo &getInfoForType(QualType Ty) const; |
211 | |
212 | public: |
213 | |
214 | |
215 | |
216 | |
217 | const ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) const; |
218 | |
219 | ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) { |
220 | const auto &This = *this; |
221 | return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind)); |
222 | } |
223 | |
224 | private: |
225 | const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const; |
226 | |
227 | private: |
228 | friend class ASTContext; |
229 | |
230 | explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {} |
231 | |
232 | const ASTContext &Ctx; |
233 | |
234 | |
235 | |
236 | mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data; |
237 | mutable NamespaceDecl *StdNS = nullptr; |
238 | }; |
239 | |
240 | } |
241 | |
242 | #endif |
243 | |