Warning: That file was not part of the compilation database. It may have many parsing errors.

1//===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the Comparison Category enum and data types, which
11// store the types and expressions needed to support operator<=>
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_COMPARISONCATEGORIES_H
16#define LLVM_CLANG_AST_COMPARISONCATEGORIES_H
17
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/APSInt.h"
20#include "llvm/ADT/DenseMap.h"
21#include <array>
22#include <cassert>
23
24namespace llvm {
25 class StringRef;
26 class APSInt;
27}
28
29namespace clang {
30
31class ASTContext;
32class VarDecl;
33class CXXRecordDecl;
34class Sema;
35class QualType;
36class NamespaceDecl;
37
38/// An enumeration representing the different comparison categories
39/// types.
40///
41/// C++2a [cmp.categories.pre] The types weak_equality, strong_equality,
42/// partial_ordering, weak_ordering, and strong_ordering are collectively
43/// termed the comparison category types.
44enum class ComparisonCategoryType : unsigned char {
45 WeakEquality,
46 StrongEquality,
47 PartialOrdering,
48 WeakOrdering,
49 StrongOrdering,
50 First = WeakEquality,
51 Last = StrongOrdering
52};
53
54/// An enumeration representing the possible results of a three-way
55/// comparison. These values map onto instances of comparison category types
56/// defined in the standard library. e.g. 'std::strong_ordering::less'.
57enum class ComparisonCategoryResult : unsigned char {
58 Equal,
59 Equivalent,
60 Nonequivalent,
61 Nonequal,
62 Less,
63 Greater,
64 Unordered,
65 Last = Unordered
66};
67
68class ComparisonCategoryInfo {
69 friend class ComparisonCategories;
70 friend class Sema;
71
72public:
73 ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD,
74 ComparisonCategoryType Kind)
75 : Ctx(Ctx), Record(RD), Kind(Kind) {}
76
77 struct ValueInfo {
78 ComparisonCategoryResult Kind;
79 VarDecl *VD;
80
81 ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
82 : Kind(Kind), VD(VD) {}
83
84 /// True iff we've successfully evaluated the variable as a constant
85 /// expression and extracted its integer value.
86 bool hasValidIntValue() const;
87
88 /// Get the constant integer value used by this variable to represent
89 /// the comparison category result type.
90 llvm::APSInt getIntValue() const;
91 };
92private:
93 const ASTContext &Ctx;
94
95 /// A map containing the comparison category result decls from the
96 /// standard library. The key is a value of ComparisonCategoryResult.
97 mutable llvm::SmallVector<
98 ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1>
99 Objects;
100
101 /// Lookup the ValueInfo struct for the specified ValueKind. If the
102 /// VarDecl for the value cannot be found, nullptr is returned.
103 ///
104 /// If the ValueInfo does not have a valid integer value the variable
105 /// is evaluated as a constant expression to determine that value.
106 ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const;
107
108public:
109 /// The declaration for the comparison category type from the
110 /// standard library.
111 // FIXME: Make this const
112 CXXRecordDecl *Record = nullptr;
113
114 /// The Kind of the comparison category type
115 ComparisonCategoryType Kind;
116
117public:
118 QualType getType() const;
119
120 const ValueInfo *getValueInfo(ComparisonCategoryResult ValueKind) const {
121 ValueInfo *Info = lookupValueInfo(ValueKind);
122 assert(Info &&
123 "comparison category does not contain the specified result kind");
124 assert(Info->hasValidIntValue() &&
125 "couldn't determine the integer constant for this value");
126 return Info;
127 }
128
129 /// True iff the comparison category is an equality comparison.
130 bool isEquality() const { return !isOrdered(); }
131
132 /// True iff the comparison category is a relational comparison.
133 bool isOrdered() const {
134 using CCK = ComparisonCategoryType;
135 return Kind == CCK::PartialOrdering || Kind == CCK::WeakOrdering ||
136 Kind == CCK::StrongOrdering;
137 }
138
139 /// True iff the comparison is "strong". i.e. it checks equality and
140 /// not equivalence.
141 bool isStrong() const {
142 using CCK = ComparisonCategoryType;
143 return Kind == CCK::StrongEquality || Kind == CCK::StrongOrdering;
144 }
145
146 /// True iff the comparison is not totally ordered.
147 bool isPartial() const {
148 using CCK = ComparisonCategoryType;
149 return Kind == CCK::PartialOrdering;
150 }
151
152 /// Converts the specified result kind into the the correct result kind
153 /// for this category. Specifically it lowers strong equality results to
154 /// weak equivalence if needed.
155 ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
156 using CCR = ComparisonCategoryResult;
157 if (!isStrong()) {
158 if (Res == CCR::Equal)
159 return CCR::Equivalent;
160 if (Res == CCR::Nonequal)
161 return CCR::Nonequivalent;
162 }
163 return Res;
164 }
165
166 const ValueInfo *getEqualOrEquiv() const {
167 return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal));
168 }
169 const ValueInfo *getNonequalOrNonequiv() const {
170 assert(isEquality());
171 return getValueInfo(makeWeakResult(ComparisonCategoryResult::Nonequal));
172 }
173 const ValueInfo *getLess() const {
174 assert(isOrdered());
175 return getValueInfo(ComparisonCategoryResult::Less);
176 }
177 const ValueInfo *getGreater() const {
178 assert(isOrdered());
179 return getValueInfo(ComparisonCategoryResult::Greater);
180 }
181 const ValueInfo *getUnordered() const {
182 assert(isPartial());
183 return getValueInfo(ComparisonCategoryResult::Unordered);
184 }
185};
186
187class ComparisonCategories {
188public:
189 static StringRef getCategoryString(ComparisonCategoryType Kind);
190 static StringRef getResultString(ComparisonCategoryResult Kind);
191
192 /// Return the list of results which are valid for the specified
193 /// comparison category type.
194 static std::vector<ComparisonCategoryResult>
195 getPossibleResultsForType(ComparisonCategoryType Type);
196
197 /// Return the comparison category information for the category
198 /// specified by 'Kind'.
199 const ComparisonCategoryInfo &getInfo(ComparisonCategoryType Kind) const {
200 const ComparisonCategoryInfo *Result = lookupInfo(Kind);
201 assert(Result != nullptr &&
202 "information for specified comparison category has not been built");
203 return *Result;
204 }
205
206 /// Return the comparison category information as specified by
207 /// `getCategoryForType(Ty)`. If the information is not already cached,
208 /// the declaration is looked up and a cache entry is created.
209 /// NOTE: Lookup is expected to succeed. Use lookupInfo if failure is
210 /// possible.
211 const ComparisonCategoryInfo &getInfoForType(QualType Ty) const;
212
213public:
214 /// Return the cached comparison category information for the
215 /// specified 'Kind'. If no cache entry is present the comparison category
216 /// type is looked up. If lookup fails nullptr is returned. Otherwise, a
217 /// new cache entry is created and returned
218 const ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) const;
219
220 ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) {
221 const auto &This = *this;
222 return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
223 }
224
225private:
226 const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
227
228private:
229 friend class ASTContext;
230
231 explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {}
232
233 const ASTContext &Ctx;
234
235 /// A map from the ComparisonCategoryType (represented as 'char') to the
236 /// cached information for the specified category.
237 mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data;
238 mutable NamespaceDecl *StdNS = nullptr;
239};
240
241} // namespace clang
242
243#endif
244

Warning: That file was not part of the compilation database. It may have many parsing errors.