clang  14.0.0git
ComparisonCategories.h
Go to the documentation of this file.
1 //===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the Comparison Category enum and data types, which
10 // store the types and expressions needed to support operator<=>
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 #include <vector>
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 {
50 };
51 
52 /// Determine the common comparison type, as defined in C++2a
53 /// [class.spaceship]p4.
56  return A < B ? A : B;
57 }
58 
59 /// Get the comparison category that should be used when comparing values of
60 /// type \c T.
62 
63 /// An enumeration representing the possible results of a three-way
64 /// comparison. These values map onto instances of comparison category types
65 /// defined in the standard library. e.g. 'std::strong_ordering::less'.
67  Equal,
68  Equivalent,
69  Less,
70  Greater,
71  Unordered,
72  Last = Unordered
73 };
74 
76  friend class ComparisonCategories;
77  friend class Sema;
78 
79 public:
82  : Ctx(Ctx), Record(RD), Kind(Kind) {}
83 
84  struct ValueInfo {
87 
89  : Kind(Kind), VD(VD) {}
90 
91  /// True iff we've successfully evaluated the variable as a constant
92  /// expression and extracted its integer value.
93  bool hasValidIntValue() const;
94 
95  /// Get the constant integer value used by this variable to represent
96  /// the comparison category result type.
97  llvm::APSInt getIntValue() const;
98  };
99 private:
100  const ASTContext &Ctx;
101 
102  /// A map containing the comparison category result decls from the
103  /// standard library. The key is a value of ComparisonCategoryResult.
104  mutable llvm::SmallVector<
105  ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1>
106  Objects;
107 
108  /// Lookup the ValueInfo struct for the specified ValueKind. If the
109  /// VarDecl for the value cannot be found, nullptr is returned.
110  ///
111  /// If the ValueInfo does not have a valid integer value the variable
112  /// is evaluated as a constant expression to determine that value.
113  ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const;
114 
115 public:
116  /// The declaration for the comparison category type from the
117  /// standard library.
118  const CXXRecordDecl *Record = nullptr;
119 
120  /// The Kind of the comparison category type
122 
123 public:
124  QualType getType() const;
125 
127  ValueInfo *Info = lookupValueInfo(ValueKind);
128  assert(Info &&
129  "comparison category does not contain the specified result kind");
130  assert(Info->hasValidIntValue() &&
131  "couldn't determine the integer constant for this value");
132  return Info;
133  }
134 
135  /// True iff the comparison is "strong". i.e. it checks equality and
136  /// not equivalence.
137  bool isStrong() const {
138  using CCK = ComparisonCategoryType;
139  return Kind == CCK::StrongOrdering;
140  }
141 
142  /// True iff the comparison is not totally ordered.
143  bool isPartial() const {
144  using CCK = ComparisonCategoryType;
145  return Kind == CCK::PartialOrdering;
146  }
147 
148  /// Converts the specified result kind into the correct result kind
149  /// for this category. Specifically it lowers strong equality results to
150  /// weak equivalence if needed.
152  using CCR = ComparisonCategoryResult;
153  if (!isStrong() && Res == CCR::Equal)
154  return CCR::Equivalent;
155  return Res;
156  }
157 
158  const ValueInfo *getEqualOrEquiv() const {
160  }
161  const ValueInfo *getLess() const {
163  }
164  const ValueInfo *getGreater() const {
166  }
167  const ValueInfo *getUnordered() const {
168  assert(isPartial());
170  }
171 };
172 
174 public:
177 
178  /// Return the list of results which are valid for the specified
179  /// comparison category type.
180  static std::vector<ComparisonCategoryResult>
182 
183  /// Return the comparison category information for the category
184  /// specified by 'Kind'.
186  const ComparisonCategoryInfo *Result = lookupInfo(Kind);
187  assert(Result != nullptr &&
188  "information for specified comparison category has not been built");
189  return *Result;
190  }
191 
192  /// Return the comparison category information as specified by
193  /// `getCategoryForType(Ty)`. If the information is not already cached,
194  /// the declaration is looked up and a cache entry is created.
195  /// NOTE: Lookup is expected to succeed. Use lookupInfo if failure is
196  /// possible.
198 
199 public:
200  /// Return the cached comparison category information for the
201  /// specified 'Kind'. If no cache entry is present the comparison category
202  /// type is looked up. If lookup fails nullptr is returned. Otherwise, a
203  /// new cache entry is created and returned
205 
207  const auto &This = *this;
208  return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
209  }
210 
212 
213 private:
214  friend class ASTContext;
215 
216  explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {}
217 
218  const ASTContext &Ctx;
219 
220  /// A map from the ComparisonCategoryType (represented as 'char') to the
221  /// cached information for the specified category.
222  mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data;
223  mutable NamespaceDecl *StdNS = nullptr;
224 };
225 
226 } // namespace clang
227 
228 #endif
clang::getComparisonCategoryForBuiltinCmp
Optional< ComparisonCategoryType > getComparisonCategoryForBuiltinCmp(QualType T)
Get the comparison category that should be used when comparing values of type T.
Definition: ComparisonCategories.cpp:24
llvm
Definition: Dominators.h:30
llvm::SmallVector
Definition: LLVM.h:38
clang::ComparisonCategoryInfo::ValueInfo::hasValidIntValue
bool hasValidIntValue() const
True iff we've successfully evaluated the variable as a constant expression and extracted its integer...
Definition: ComparisonCategories.cpp:43
clang::ComparisonCategoryInfo::ValueInfo::VD
VarDecl * VD
Definition: ComparisonCategories.h:86
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::ComparisonCategories::getInfoForType
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
Definition: ComparisonCategories.cpp:160
clang::ComparisonCategoryInfo::isStrong
bool isStrong() const
True iff the comparison is "strong".
Definition: ComparisonCategories.h:137
llvm::Optional
Definition: LLVM.h:40
clang::ComparisonCategoryType::First
@ First
clang::ComparisonCategoryInfo::ValueInfo::getIntValue
llvm::APSInt getIntValue() const
Get the constant integer value used by this variable to represent the comparison category result type...
Definition: ComparisonCategories.cpp:66
clang::ComparisonCategoryInfo::getUnordered
const ValueInfo * getUnordered() const
Definition: ComparisonCategories.h:167
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1490
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::ComparisonCategoryInfo::Record
const CXXRecordDecl * Record
The declaration for the comparison category type from the standard library.
Definition: ComparisonCategories.h:118
clang::ComparisonCategoryInfo::ValueInfo::ValueInfo
ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
Definition: ComparisonCategories.h:88
clang::ComparisonCategories::getPossibleResultsForType
static std::vector< ComparisonCategoryResult > getPossibleResultsForType(ComparisonCategoryType Type)
Return the list of results which are valid for the specified comparison category type.
Definition: ComparisonCategories.cpp:202
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::ComparisonCategories
Definition: ComparisonCategories.h:173
clang::commonComparisonType
ComparisonCategoryType commonComparisonType(ComparisonCategoryType A, ComparisonCategoryType B)
Determine the common comparison type, as defined in C++2a [class.spaceship]p4.
Definition: ComparisonCategories.h:54
clang::ComparisonCategoryType
ComparisonCategoryType
An enumeration representing the different comparison categories types.
Definition: ComparisonCategories.h:44
clang::ComparisonCategories::lookupInfoForType
const ComparisonCategoryInfo * lookupInfoForType(QualType Ty) const
Definition: ComparisonCategories.cpp:125
clang::ComparisonCategoryResult::Less
@ Less
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
clang::ComparisonCategoryResult::Last
@ Last
clang::ComparisonCategories::lookupInfo
ComparisonCategoryInfo * lookupInfo(ComparisonCategoryType Kind)
Definition: ComparisonCategories.h:206
clang::ComparisonCategories::lookupInfo
const ComparisonCategoryInfo * lookupInfo(ComparisonCategoryType Kind) const
Return the cached comparison category information for the specified 'Kind'.
Definition: ComparisonCategories.cpp:112
clang::ComparisonCategoryInfo
Definition: ComparisonCategories.h:75
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:255
clang::ComparisonCategoryInfo::ValueInfo::Kind
ComparisonCategoryResult Kind
Definition: ComparisonCategories.h:85
clang::ComparisonCategoryInfo::getValueInfo
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
Definition: ComparisonCategories.h:126
clang::ComparisonCategoryInfo::ComparisonCategoryInfo
ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD, ComparisonCategoryType Kind)
Definition: ComparisonCategories.h:80
clang::ComparisonCategories::getCategoryString
static StringRef getCategoryString(ComparisonCategoryType Kind)
Definition: ComparisonCategories.cpp:171
clang::ComparisonCategoryType::WeakOrdering
@ WeakOrdering
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:355
LLVM.h
clang::ComparisonCategoryResult::Equivalent
@ Equivalent
clang::ComparisonCategoryInfo::isPartial
bool isPartial() const
True iff the comparison is not totally ordered.
Definition: ComparisonCategories.h:143
clang::ComparisonCategoryResult::Equal
@ Equal
clang::ComparisonCategoryResult::Unordered
@ Unordered
clang::ComparisonCategoryInfo::getType
QualType getType() const
Definition: ComparisonCategories.cpp:166
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::ComparisonCategories::getInfo
const ComparisonCategoryInfo & getInfo(ComparisonCategoryType Kind) const
Return the comparison category information for the category specified by 'Kind'.
Definition: ComparisonCategories.h:185
clang::interp::This
bool This(InterpState &S, CodePtr OpPC)
Definition: Interp.h:829
clang::ComparisonCategoryInfo::getEqualOrEquiv
const ValueInfo * getEqualOrEquiv() const
Definition: ComparisonCategories.h:158
clang
Definition: CalledOnceCheck.h:17
clang::ComparisonCategoryType::Last
@ Last
clang::ComparisonCategoryInfo::makeWeakResult
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Definition: ComparisonCategories.h:151
clang::ComparisonCategoryResult
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
Definition: ComparisonCategories.h:66
clang::ComparisonCategoryType::StrongOrdering
@ StrongOrdering
clang::ComparisonCategoryInfo::Kind
ComparisonCategoryType Kind
The Kind of the comparison category type.
Definition: ComparisonCategories.h:121
unsigned
clang::ComparisonCategoryType::PartialOrdering
@ PartialOrdering
clang::ComparisonCategoryInfo::ValueInfo
Definition: ComparisonCategories.h:84
clang::ComparisonCategoryResult::Greater
@ Greater
clang::ComparisonCategoryInfo::getLess
const ValueInfo * getLess() const
Definition: ComparisonCategories.h:161
clang::ComparisonCategories::getResultString
static StringRef getResultString(ComparisonCategoryResult Kind)
Definition: ComparisonCategories.cpp:184
clang::ComparisonCategoryInfo::getGreater
const ValueInfo * getGreater() const
Definition: ComparisonCategories.h:164
clang::NamespaceDecl
Represent a C++ namespace.
Definition: Decl.h:542