================
@@ -1008,47 +1010,163 @@ struct Context {
 
 using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
 
+/// Describes optional constraints on a C++ method's implicit object parameter.
+struct FunctionObjectSelector {
+  std::optional<bool> Const;
+  std::optional<bool> Volatile;
+  std::optional<RefQualifierKind> Ref;
+
+  std::string format() const;
+};
+
+inline bool operator==(const FunctionObjectSelector &LHS,
+                       const FunctionObjectSelector &RHS) {
+  return LHS.Const == RHS.Const && LHS.Volatile == RHS.Volatile &&
+         LHS.Ref == RHS.Ref;
+}
+
+inline bool operator!=(const FunctionObjectSelector &LHS,
+                       const FunctionObjectSelector &RHS) {
+  return !(LHS == RHS);
+}
+
+inline std::string FunctionObjectSelector::format() const {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  llvm::SmallVector<std::string, 3> Parts;
+
+  if (Const)
+    Parts.push_back(std::string("Const: ") + (*Const ? "true" : "false"));
+  if (Volatile)
+    Parts.push_back(std::string("Volatile: ") + (*Volatile ? "true" : 
"false"));
+  if (Ref) {
+    std::string Ref = "Ref: ";
+    switch (*this->Ref) {
+    case RQ_None:
+      Ref += "none";
+      break;
+    case RQ_LValue:
+      Ref += "lvalue";
+      break;
+    case RQ_RValue:
+      Ref += "rvalue";
+      break;
+    }
+    Parts.push_back(Ref);
+  }
+
+  OS << "Object{";
+  llvm::interleaveComma(Parts, OS);
+  OS << "}";
+  return Result;
+}
+
+/// Describes a C++ function selector composed from optional exact explicit
+/// parameters plus optional implicit object constraints.
+struct FunctionSelector {
+  std::optional<llvm::SmallVector<std::string, 4>> Parameters;
+  std::optional<FunctionObjectSelector> Object;
+
+  std::string format() const;
+};
+
+inline bool operator==(const FunctionSelector &LHS,
+                       const FunctionSelector &RHS) {
+  return LHS.Parameters == RHS.Parameters && LHS.Object == RHS.Object;
+}
+
+inline bool operator!=(const FunctionSelector &LHS,
+                       const FunctionSelector &RHS) {
+  return !(LHS == RHS);
+}
+
+inline std::string formatAPINotesFunctionSelector(
+    std::optional<llvm::ArrayRef<std::string>> Parameters,
+    std::optional<FunctionObjectSelector> Object) {
+  std::string Result;
+  if (Parameters)
+    Result = (llvm::Twine("Where.Parameters ") +
+              formatAPINotesParameterSelector(*Parameters))
+                 .str();
+
+  if (Object) {
+    if (!Result.empty())
+      Result += " ";
+    else
+      Result = "Where.Object ";
+    Result += Object->format();
+  }
+
+  return Result;
+}
+
+inline std::string FunctionSelector::format() const {
+  std::optional<llvm::ArrayRef<std::string>> Parameters;
+  if (this->Parameters)
+    Parameters = llvm::ArrayRef<std::string>(*this->Parameters);
+  return formatAPINotesFunctionSelector(Parameters, Object);
+}
+
+struct FunctionTableSelectorKey {
+  std::optional<llvm::SmallVector<IdentifierID, 2>> Parameters;
----------------
Xazax-hun wrote:

Nit: here we use 2 as the small vector size but almost everywhere else we use 
2. Is there a reason or should this be consistent?

https://github.com/llvm/llvm-project/pull/216148
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to