clang 8.0.0

ComparisonCategories.h
Go to the documentation of this file.
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
24 namespace llvm {
25 class StringRef;
26 class APSInt;
27 }
28
29 namespace clang {
30
31 class ASTContext;
32 class VarDecl;
33 class CXXRecordDecl;
34 class Sema;
35 class QualType;
36 class 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.
44 enum 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'.
57 enum class ComparisonCategoryResult : unsigned char {
58 Equal,
59 Equivalent,
60 Nonequivalent,
61 Nonequal,
62 Less,
63 Greater,
64 Unordered,
65 Last = Unordered
66 };
67
68 class ComparisonCategoryInfo {
69 friend class ComparisonCategories;
70 friend class Sema;
71
72 public:
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 };
92 private:
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
108 public:
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
117 public:
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
187 class ComparisonCategories {
188 public:
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
213 public:
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
225 private:
226 const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
227
228 private:
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
clang::ComparisonCategoryInfo
Definition: ComparisonCategories.h:68
clang::ComparisonCategoryInfo::ValueInfo
Definition: ComparisonCategories.h:77
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:638
llvm
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:30
clang::ComparisonCategoryResult::Equal
clang::ComparisonCategoryResult::Greater
clang::ComparisonCategoryInfo::Kind
ComparisonCategoryType Kind
The Kind of the comparison category type.
Definition: ComparisonCategories.h:115
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1407
clang::NamespaceDecl
Represent a C++ namespace.
Definition: Decl.h:515
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:813
clang::ComparisonCategoryResult::Equivalent
clang::ComparisonCategoryType::PartialOrdering
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
clang::ComparisonCategoryInfo::ValueInfo::VD
VarDecl * VD
Definition: ComparisonCategories.h:79
clang::ComparisonCategoryResult::Nonequal
clang::ComparisonCategoryResult
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
Definition: ComparisonCategories.h:57
clang::ComparisonCategoryInfo::isPartial
bool isPartial() const
True iff the comparison is not totally ordered.
Definition: ComparisonCategories.h:147
LLVM.h
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
clang::ComparisonCategoryType::First
clang::ComparisonCategoryResult::Less
clang::ComparisonCategoryInfo::isEquality
bool isEquality() const
True iff the comparison category is an equality comparison.
Definition: ComparisonCategories.h:130
clang::ComparisonCategoryInfo::getValueInfo
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Definition: ComparisonCategories.h:120
clang::ComparisonCategoryType::StrongOrdering
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:278
clang::ComparisonCategoryInfo::getNonequalOrNonequiv
const ValueInfo * getNonequalOrNonequiv() const
Definition: ComparisonCategories.h:169
clang::ComparisonCategoryType::WeakEquality
clang::ComparisonCategoryType::Last
clang::ComparisonCategoryType::WeakOrdering
clang::ComparisonCategoryInfo::ValueInfo::hasValidIntValue
bool hasValidIntValue() const
True iff we&#39;ve successfully evaluated the variable as a constant expression and extracted its integer...
Definition: ComparisonCategories.cpp:23
clang::ComparisonCategories
Definition: ComparisonCategories.h:187
clang::ComparisonCategoryInfo::getGreater
const ValueInfo * getGreater() const
Definition: ComparisonCategories.h:177
Kind
Kind
Definition: ChrootChecker.cpp:29
clang::ComparisonCategoryInfo::isOrdered
bool isOrdered() const
True iff the comparison category is a relational comparison.
Definition: ComparisonCategories.h:133
clang::ComparisonCategoryInfo::getLess
const ValueInfo * getLess() const
Definition: ComparisonCategories.h:173
llvm::SmallVector
Definition: LLVM.h:36
clang::ComparisonCategories::lookupInfo
ComparisonCategoryInfo * lookupInfo(ComparisonCategoryType Kind)
Definition: ComparisonCategories.h:220
clang::ComparisonCategoryType::StrongEquality
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::ComparisonCategoryResult::Nonequivalent
clang::ComparisonCategoryInfo::ComparisonCategoryInfo
ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD, ComparisonCategoryType Kind)
Definition: ComparisonCategories.h:73
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
clang::ComparisonCategoryInfo::isStrong
bool isStrong() const
True iff the comparison is "strong".
Definition: ComparisonCategories.h:141
clang::ComparisonCategoryResult::Unordered
clang::ComparisonCategoryInfo::getEqualOrEquiv
const ValueInfo * getEqualOrEquiv() const
Definition: ComparisonCategories.h:166
clang::ComparisonCategories::getInfo
const ComparisonCategoryInfo & getInfo(ComparisonCategoryType Kind) const
Return the comparison category information for the category specified by &#39;Kind&#39;.
Definition: ComparisonCategories.h:199
clang::ComparisonCategoryInfo::ValueInfo::ValueInfo
ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
Definition: ComparisonCategories.h:81
clang::ComparisonCategoryType
ComparisonCategoryType
An enumeration representing the different comparison categories types.
Definition: ComparisonCategories.h:44
clang::ComparisonCategoryInfo::getUnordered
const ValueInfo * getUnordered() const
Definition: ComparisonCategories.h:181
clang::ComparisonCategoryInfo::ValueInfo::Kind
ComparisonCategoryResult Kind
Definition: ComparisonCategories.h:78
clang::ComparisonCategoryInfo::makeWeakResult
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the the correct result kind for this category.
Definition: ComparisonCategories.h:155