[clang] [APINotes] Diagnose invalid Where.Parameters selectors (PR #209408)

Gábor Horváth via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 27 08:14:36 PDT 2026


================
@@ -988,6 +999,89 @@ struct Context {
   Context(ContextID id, ContextKind kind) : id(id), kind(kind) {}
 };
 
+using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
+
+/// 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.
+struct FunctionTableKey {
+  uint32_t parentContextID;
+  uint32_t nameID;
+  std::optional<llvm::SmallVector<IdentifierID, 2>> parameterTypeIDs;
+
+  FunctionTableKey() : parentContextID(-1), nameID(-1) {}
+
+  FunctionTableKey(uint32_t ParentContextID, uint32_t NameID)
+      : parentContextID(ParentContextID), nameID(NameID) {}
+
+  FunctionTableKey(uint32_t ParentContextID, uint32_t NameID,
+                   const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
+      : parentContextID(ParentContextID), nameID(NameID) {
+    parameterTypeIDs.emplace(ParameterTypeIDs.begin(), ParameterTypeIDs.end());
+  }
+
+  FunctionTableKey(std::optional<Context> ParentCtx, IdentifierID NameID)
+      : parentContextID(ParentCtx ? ParentCtx->id.Value
+                                  : static_cast<uint32_t>(-1)),
+        nameID(NameID) {}
+
+  FunctionTableKey(std::optional<Context> ParentCtx, IdentifierID NameID,
+                   const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
+      : parentContextID(ParentCtx ? ParentCtx->id.Value
+                                  : static_cast<uint32_t>(-1)),
+        nameID(NameID) {
+    parameterTypeIDs.emplace(ParameterTypeIDs.begin(), ParameterTypeIDs.end());
+  }
+
+  llvm::hash_code hashValue() const {
+    auto Hash = llvm::hash_combine(parentContextID, nameID,
+                                   static_cast<bool>(parameterTypeIDs));
+    if (parameterTypeIDs) {
+      Hash = llvm::hash_combine(Hash, parameterTypeIDs->size());
+      for (IdentifierID TypeID : *parameterTypeIDs)
+        Hash = llvm::hash_combine(Hash, static_cast<unsigned>(TypeID));
+    }
+    return Hash;
+  }
+};
+
+inline bool operator==(const FunctionTableKey &LHS,
+                       const FunctionTableKey &RHS) {
+  return LHS.parentContextID == RHS.parentContextID &&
+         LHS.nameID == RHS.nameID &&
+         LHS.parameterTypeIDs == RHS.parameterTypeIDs;
+}
+
+/// Stable reader-facing identity for an API notes function selector entry.
+///
+/// The key keeps the serialized function table identity together with the table
+/// kind. parentContextID names only the declaration context and does not say
+/// whether the entry came from the global-function or C++-method table.
+struct APINotesFunctionSelectorKey {
+  FunctionTableKey Key;
+  bool IsCXXMethod = false;
+
+  APINotesFunctionSelectorKey getWithoutParameterSelector() const {
+    return {FunctionTableKey(Key.parentContextID, Key.nameID), IsCXXMethod};
+  }
+
+  llvm::hash_code hashValue() const {
+    return llvm::hash_combine(Key.hashValue(), IsCXXMethod);
+  }
+};
+
+inline bool operator==(const APINotesFunctionSelectorKey &LHS,
+                       const APINotesFunctionSelectorKey &RHS) {
+  return LHS.Key == RHS.Key && LHS.IsCXXMethod == RHS.IsCXXMethod;
+}
+
+/// Exact function selector key plus parameter spellings used for diagnostics.
+struct APINotesFunctionSelector {
+  APINotesFunctionSelectorKey Key;
+  llvm::SmallVector<std::string, 4> Parameters;
----------------
Xazax-hun wrote:

If these spellings are used for diagnostics, I wonder if it would be cleaner to get read of the comment above the struct and call this `ParameterSpellings` and use a comment on a field that this is for diagnostics. 

https://github.com/llvm/llvm-project/pull/209408


More information about the cfe-commits mailing list