================
@@ -1008,47 +1010,165 @@ 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==(FunctionObjectSelector LHS, FunctionObjectSelector RHS) 
{
+  return LHS.Const == RHS.Const && LHS.Volatile == RHS.Volatile &&
+         LHS.Ref == RHS.Ref;
+}
+
+inline bool operator!=(FunctionObjectSelector LHS, 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;
+
+  void setParameters(llvm::ArrayRef<std::string> NewParameters) {
+    Parameters.emplace(NewParameters.begin(), NewParameters.end());
+  }
+
+  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, 4>> Parameters;
+  std::optional<FunctionObjectSelector> Object;
+};
+
 /// A key for a stored global-function or C++-method API notes entry.
 ///
 /// The key is represented by the ID of its parent context, the declaration
-/// name, and optional exact parameter types.
+/// name, and optional exact parameter/object selector data.
 struct FunctionTableKey {
   uint32_t parentContextID;
   uint32_t nameID;
-  std::optional<llvm::SmallVector<IdentifierID, 2>> parameterTypeIDs;
+  std::optional<llvm::SmallVector<IdentifierID, 4>> parameterTypeIDs;
----------------
Xazax-hun wrote:

Should we have a single `FunctionTableSelectorKey` member here?

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