llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: StoeckOverflow

<details>
<summary>Changes</summary>

This PR teaches Sema to apply function-like `Where.Parameters` selectors for 
API notes.

It builds on #<!-- -->204147 by using the serialized `Where.Parameters` 
selector keys in Sema. For each `FunctionDecl` / `CXXMethodDecl`, Sema derives 
an exact parameter selector from the declaration’s `FunctionProtoType`. Broad 
name-only API notes lookup still runs first, preserving existing behavior. If 
Clang can form a parameter selector, Sema then performs an exact selector 
lookup and applies that result second, allowing overload-specific notes to 
refine same-name broad notes.

Tests:
- Adds end-to-end module APINotes Sema coverage (`.apinotes` source -&gt; 
binary APINotes -&gt; reader lookup -&gt; Sema matching -&gt; AST result)
- Covers core matching behavior for global functions and C++ methods, including 
same-name overloads, exact empty selectors, broad-plus-exact coexistence and 
mismatched selectors
- Covers important edge cases: default arguments, static methods, alias 
spellings remaining non-canonicalized, by-value `const`, namespaced functions, 
and overloaded operators.

This PR does not add duplicate-selector or unmatched-selector diagnostics. 
Those remain for a follow-up diagnostics PR.

**Note**: this PR is stacked on top of #<!-- -->204147, which has not merged 
yet. Until that PR gets merged, GitHub will also show the serialization changes 
in this diff. The changes specific to this PR are contained in the top commit, 
ca9bc2b80e6beb3bf41d3f9914a4e41defaceb2b (`[APINotes] Apply Where.Parameters 
selectors in Sema`).

Reviewers: @<!-- -->Xazax-hun @<!-- -->j-hui @<!-- -->egorzhdan

---

Patch is 50.94 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/205307.diff


16 Files Affected:

- (modified) clang/include/clang/APINotes/APINotesReader.h (+31) 
- (modified) clang/include/clang/APINotes/APINotesWriter.h (+17) 
- (modified) clang/lib/APINotes/APINotesFormat.h (+103-1) 
- (modified) clang/lib/APINotes/APINotesReader.cpp (+145-16) 
- (modified) clang/lib/APINotes/APINotesWriter.cpp (+89-21) 
- (modified) clang/lib/APINotes/APINotesYAMLCompiler.cpp (+35-11) 
- (modified) clang/lib/Sema/SemaAPINotes.cpp (+45) 
- (added) clang/test/APINotes/Inputs/Headers/WhereParametersSema.apinotes 
(+126) 
- (added) clang/test/APINotes/Inputs/Headers/WhereParametersSema.h (+51) 
- (modified) clang/test/APINotes/Inputs/Headers/module.modulemap (+5) 
- (modified) 
clang/test/APINotes/Inputs/WhereParametersConvertDiag/APINotes.apinotes (+8-1) 
- (modified) 
clang/test/APINotes/Inputs/WhereParametersConvertDiag/WhereParametersConvertDiag.h
 (+2) 
- (added) 
clang/test/APINotes/Inputs/WhereParametersEmptyWhereDiag/APINotes.apinotes 
(+12) 
- (added) 
clang/test/APINotes/Inputs/WhereParametersEmptyWhereDiag/WhereParametersConvertDiag.h
 (+10) 
- (modified) clang/test/APINotes/where-parameters-convert-diags.cpp (+3-2) 
- (added) clang/test/APINotes/where-parameters-sema.cpp (+110) 


``````````diff
diff --git a/clang/include/clang/APINotes/APINotesReader.h 
b/clang/include/clang/APINotes/APINotesReader.h
index 875c314b284c1..8e748b5803189 100644
--- a/clang/include/clang/APINotes/APINotesReader.h
+++ b/clang/include/clang/APINotes/APINotesReader.h
@@ -16,10 +16,12 @@
 #define LLVM_CLANG_APINOTES_READER_H
 
 #include "clang/APINotes/Types.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/VersionTuple.h"
 #include <memory>
+#include <optional>
 
 namespace clang {
 namespace api_notes {
@@ -159,6 +161,13 @@ class APINotesReader {
   VersionedInfo<CXXMethodInfo> lookupCXXMethod(ContextID CtxID,
                                                llvm::StringRef Name);
 
+  /// Look for information regarding the given C++ method with an exact
+  /// parameter selector. An empty parameter list uses an exact zero-parameter
+  /// key, and a non-empty list uses an exact ordered parameter key.
+  VersionedInfo<CXXMethodInfo>
+  lookupCXXMethod(ContextID CtxID, llvm::StringRef Name,
+                  llvm::ArrayRef<llvm::StringRef> Parameters);
+
   /// Look for information regarding the given global variable.
   ///
   /// \param Name The name of the global variable.
@@ -177,6 +186,14 @@ class APINotesReader {
   lookupGlobalFunction(llvm::StringRef Name,
                        std::optional<Context> Ctx = std::nullopt);
 
+  /// Look for information regarding the given global function with an exact
+  /// parameter selector. An empty parameter list uses an exact zero-parameter
+  /// key, and a non-empty list uses an exact ordered parameter key.
+  VersionedInfo<GlobalFunctionInfo>
+  lookupGlobalFunction(llvm::StringRef Name,
+                       llvm::ArrayRef<llvm::StringRef> Parameters,
+                       std::optional<Context> Ctx = std::nullopt);
+
   /// Look for information regarding the given enumerator.
   ///
   /// \param Name The name of the enumerator.
@@ -221,6 +238,20 @@ class APINotesReader {
   std::optional<ContextID>
   lookupNamespaceID(llvm::StringRef Name,
                     std::optional<ContextID> ParentNamespaceID = std::nullopt);
+
+private:
+  VersionedInfo<CXXMethodInfo> lookupCXXMethodImpl(ContextID CtxID,
+                                                   llvm::StringRef Name);
+  VersionedInfo<CXXMethodInfo>
+  lookupCXXMethodImpl(ContextID CtxID, llvm::StringRef Name,
+                      llvm::ArrayRef<llvm::StringRef> Parameters);
+
+  VersionedInfo<GlobalFunctionInfo>
+  lookupGlobalFunctionImpl(llvm::StringRef Name, std::optional<Context> Ctx);
+  VersionedInfo<GlobalFunctionInfo>
+  lookupGlobalFunctionImpl(llvm::StringRef Name,
+                           llvm::ArrayRef<llvm::StringRef> Parameters,
+                           std::optional<Context> Ctx);
 };
 
 } // end namespace api_notes
diff --git a/clang/include/clang/APINotes/APINotesWriter.h 
b/clang/include/clang/APINotes/APINotesWriter.h
index 3cc16c3d959fa..5ed6686e1bb85 100644
--- a/clang/include/clang/APINotes/APINotesWriter.h
+++ b/clang/include/clang/APINotes/APINotesWriter.h
@@ -16,11 +16,13 @@
 #define LLVM_CLANG_APINOTES_WRITER_H
 
 #include "clang/APINotes/Types.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/VersionTuple.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <memory>
+#include <optional>
 
 namespace clang {
 class FileEntry;
@@ -86,6 +88,13 @@ class APINotesWriter {
   void addCXXMethod(ContextID CtxID, llvm::StringRef Name,
                     const CXXMethodInfo &Info, llvm::VersionTuple 
SwiftVersion);
 
+  /// Add information about a C++ method with an exact parameter selector. An
+  /// empty parameter list uses an exact zero-parameter key, and a non-empty
+  /// list uses an exact ordered parameter key.
+  void addCXXMethod(ContextID CtxID, llvm::StringRef Name,
+                    llvm::ArrayRef<llvm::StringRef> Parameters,
+                    const CXXMethodInfo &Info, llvm::VersionTuple 
SwiftVersion);
+
   /// Add information about a specific C record field.
   ///
   /// \param CtxID The context in which this field resides, i.e. a C/C++ tag.
@@ -110,6 +119,14 @@ class APINotesWriter {
                          const GlobalFunctionInfo &Info,
                          llvm::VersionTuple SwiftVersion);
 
+  /// Add information about a global function with an exact parameter selector.
+  /// An empty parameter list uses an exact zero-parameter key, and a non-empty
+  /// list uses an exact ordered parameter key.
+  void addGlobalFunction(std::optional<Context> Ctx, llvm::StringRef Name,
+                         llvm::ArrayRef<llvm::StringRef> Parameters,
+                         const GlobalFunctionInfo &Info,
+                         llvm::VersionTuple SwiftVersion);
+
   /// Add information about an enumerator.
   ///
   /// \param Name The name of this enumerator.
diff --git a/clang/lib/APINotes/APINotesFormat.h 
b/clang/lib/APINotes/APINotesFormat.h
index 5679ae39e9900..df67da0845baf 100644
--- a/clang/lib/APINotes/APINotesFormat.h
+++ b/clang/lib/APINotes/APINotesFormat.h
@@ -10,9 +10,13 @@
 #define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
 
 #include "clang/APINotes/Types.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/PointerEmbeddedInt.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Bitcode/BitcodeConvenience.h"
 
+#include <optional>
+
 namespace clang {
 namespace api_notes {
 /// Magic number for API notes files.
@@ -24,8 +28,9 @@ const uint16_t VERSION_MAJOR = 0;
 /// API notes file minor version number.
 ///
 /// When the format changes IN ANY WAY, this number should be incremented.
-const uint16_t VERSION_MINOR = 40; // 39 for BoundsSafety;
+const uint16_t VERSION_MINOR = 41; // 39 for BoundsSafety;
                                    // 40 for UnsafeBufferUsageAttr
+                                   // 41 for FunctionTableKey parameters
 
 const uint8_t kSwiftConforms = 1;
 const uint8_t kSwiftDoesNotConform = 2;
@@ -354,6 +359,91 @@ inline bool operator==(const SingleDeclTableKey &lhs,
   return lhs.parentContextID == rhs.parentContextID && lhs.nameID == 
rhs.nameID;
 }
 
+/// A stored C or C++ function declaration, represented by the ID of its parent
+/// context, the name of the declaration, and optional exact parameter types.
+constexpr uint8_t FunctionKeyHasParameterSelector = 0x01;
+constexpr unsigned FunctionTableKeyBaseLength =
+    sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint16_t);
+
+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;
+  }
+};
+
+template <typename GetIdentifierFn>
+std::optional<FunctionTableKey>
+getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name,
+                   GetIdentifierFn GetIdentifier) {
+  std::optional<IdentifierID> NameID = GetIdentifier(Name);
+  if (!NameID)
+    return std::nullopt;
+
+  return FunctionTableKey(ParentContextID, *NameID);
+}
+
+template <typename GetIdentifierFn>
+std::optional<FunctionTableKey>
+getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name,
+                   llvm::ArrayRef<llvm::StringRef> Parameters,
+                   GetIdentifierFn GetIdentifier) {
+  std::optional<IdentifierID> NameID = GetIdentifier(Name);
+  if (!NameID)
+    return std::nullopt;
+
+  llvm::SmallVector<IdentifierID, 2> ParameterTypeIDs;
+  ParameterTypeIDs.reserve(Parameters.size());
+  for (llvm::StringRef Parameter : Parameters) {
+    std::optional<IdentifierID> ParameterID = GetIdentifier(Parameter);
+    if (!ParameterID)
+      return std::nullopt;
+    ParameterTypeIDs.push_back(*ParameterID);
+  }
+  return FunctionTableKey(ParentContextID, *NameID, ParameterTypeIDs);
+}
+
+inline bool operator==(const FunctionTableKey &lhs,
+                       const FunctionTableKey &rhs) {
+  return lhs.parentContextID == rhs.parentContextID &&
+         lhs.nameID == rhs.nameID &&
+         lhs.parameterTypeIDs == rhs.parameterTypeIDs;
+}
+
 } // namespace api_notes
 } // namespace clang
 
@@ -401,6 +491,18 @@ template <> struct 
DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
   }
 };
 
+template <> struct DenseMapInfo<clang::api_notes::FunctionTableKey> {
+  static unsigned
+  getHashValue(const clang::api_notes::FunctionTableKey &value) {
+    return value.hashValue();
+  }
+
+  static bool isEqual(const clang::api_notes::FunctionTableKey &lhs,
+                      const clang::api_notes::FunctionTableKey &rhs) {
+    return lhs == rhs;
+  }
+};
+
 } // namespace llvm
 
 #endif
diff --git a/clang/lib/APINotes/APINotesReader.cpp 
b/clang/lib/APINotes/APINotesReader.cpp
index 7713e47cba3a9..9305a5f10b4e8 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -46,6 +46,38 @@ llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) {
   return llvm::VersionTuple(Major, Minor, Subminor, Build);
 }
 
+static FunctionTableKey readFunctionTableKey(const uint8_t *Data,
+                                             unsigned Length) {
+  assert(Length >= FunctionTableKeyBaseLength &&
+         "Unexpected function table key length");
+
+  auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
+  auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
+  uint8_t FunctionKeyFlags =
+      endian::readNext<uint8_t, llvm::endianness::little>(Data);
+  auto ParameterCount =
+      endian::readNext<uint16_t, llvm::endianness::little>(Data);
+
+  assert(Length ==
+             FunctionTableKeyBaseLength + ParameterCount * sizeof(uint32_t) &&
+         "Unexpected function table key length");
+
+  llvm::SmallVector<IdentifierID, 2> ParameterTypeIDs;
+  ParameterTypeIDs.reserve(ParameterCount);
+  for (unsigned I = 0; I != ParameterCount; ++I)
+    ParameterTypeIDs.push_back(
+        endian::readNext<uint32_t, llvm::endianness::little>(Data));
+
+  assert((FunctionKeyFlags & ~FunctionKeyHasParameterSelector) == 0 &&
+         "Unexpected function table key flags");
+  if (FunctionKeyFlags & FunctionKeyHasParameterSelector)
+    return {CtxID, NameID, ParameterTypeIDs};
+
+  assert(ParameterTypeIDs.empty() &&
+         "Broad function table key should not store parameters");
+  return {CtxID, NameID};
+}
+
 /// An on-disk hash table whose data is versioned based on the Swift version.
 template <typename Derived, typename KeyType, typename UnversionedDataType>
 class VersionedTableInfo {
@@ -527,13 +559,11 @@ class GlobalVariableTableInfo
 
 /// Used to deserialize the on-disk global function table.
 class GlobalFunctionTableInfo
-    : public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
+    : public VersionedTableInfo<GlobalFunctionTableInfo, FunctionTableKey,
                                 GlobalFunctionInfo> {
 public:
   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
-    auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
-    auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
-    return {CtxID, NameID};
+    return readFunctionTableKey(Data, Length);
   }
 
   hash_value_type ComputeHash(internal_key_type Key) {
@@ -550,13 +580,11 @@ class GlobalFunctionTableInfo
 
 /// Used to deserialize the on-disk C++ method table.
 class CXXMethodTableInfo
-    : public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey,
+    : public VersionedTableInfo<CXXMethodTableInfo, FunctionTableKey,
                                 CXXMethodInfo> {
 public:
   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
-    auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
-    auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
-    return {CtxID, NameID};
+    return readFunctionTableKey(Data, Length);
   }
 
   hash_value_type ComputeHash(internal_key_type Key) {
@@ -827,6 +855,17 @@ class APINotesReader::Implementation {
                                     llvm::SmallVectorImpl<uint64_t> &Scratch);
   llvm::Error readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
                                       llvm::SmallVectorImpl<uint64_t> 
&Scratch);
+  std::optional<FunctionTableKey> getFunctionKey(uint32_t ParentContextID,
+                                                 llvm::StringRef Name);
+  std::optional<FunctionTableKey>
+  getFunctionKey(uint32_t ParentContextID, llvm::StringRef Name,
+                 llvm::ArrayRef<llvm::StringRef> Parameters);
+  std::optional<FunctionTableKey>
+  getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name);
+  std::optional<FunctionTableKey>
+  getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name,
+                 llvm::ArrayRef<llvm::StringRef> Parameters);
+
   llvm::Error readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor,
                                       llvm::SmallVectorImpl<uint64_t> 
&Scratch);
   llvm::Error readEnumConstantBlock(llvm::BitstreamCursor &Cursor,
@@ -852,6 +891,37 @@ 
APINotesReader::Implementation::getIdentifier(llvm::StringRef Str) {
   return *Known;
 }
 
+std::optional<FunctionTableKey>
+APINotesReader::Implementation::getFunctionKey(uint32_t ParentContextID,
+                                               llvm::StringRef Name) {
+  return getFunctionKeyImpl(ParentContextID, Name, [this](llvm::StringRef S) {
+    return getIdentifier(S);
+  });
+}
+
+std::optional<FunctionTableKey> APINotesReader::Implementation::getFunctionKey(
+    uint32_t ParentContextID, llvm::StringRef Name,
+    llvm::ArrayRef<llvm::StringRef> Parameters) {
+  return getFunctionKeyImpl(
+      ParentContextID, Name, Parameters,
+      [this](llvm::StringRef S) { return getIdentifier(S); });
+}
+
+std::optional<FunctionTableKey> APINotesReader::Implementation::getFunctionKey(
+    std::optional<Context> ParentContext, llvm::StringRef Name) {
+  uint32_t ParentContextID =
+      ParentContext ? ParentContext->id.Value : static_cast<uint32_t>(-1);
+  return getFunctionKey(ParentContextID, Name);
+}
+
+std::optional<FunctionTableKey> APINotesReader::Implementation::getFunctionKey(
+    std::optional<Context> ParentContext, llvm::StringRef Name,
+    llvm::ArrayRef<llvm::StringRef> Parameters) {
+  uint32_t ParentContextID =
+      ParentContext ? ParentContext->id.Value : static_cast<uint32_t>(-1);
+  return getFunctionKey(ParentContextID, Name, Parameters);
+}
+
 std::optional<SelectorID>
 APINotesReader::Implementation::getSelector(ObjCSelectorRef Selector) {
   if (!ObjCSelectorTable || !IdentifierTable)
@@ -2268,15 +2338,45 @@ auto APINotesReader::lookupField(ContextID CtxID, 
llvm::StringRef Name)
 
 auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
     -> VersionedInfo<CXXMethodInfo> {
+  return lookupCXXMethodImpl(CtxID, Name);
+}
+
+auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name,
+                                     llvm::ArrayRef<llvm::StringRef> 
Parameters)
+    -> VersionedInfo<CXXMethodInfo> {
+  return lookupCXXMethodImpl(CtxID, Name, Parameters);
+}
+
+auto APINotesReader::lookupCXXMethodImpl(ContextID CtxID, llvm::StringRef Name)
+    -> VersionedInfo<CXXMethodInfo> {
   if (!Implementation->CXXMethodTable)
     return std::nullopt;
 
-  std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
-  if (!NameID)
+  std::optional<FunctionTableKey> Key =
+      Implementation->getFunctionKey(CtxID.Value, Name);
+  if (!Key)
     return std::nullopt;
 
-  auto Known = Implementation->CXXMethodTable->find(
-      SingleDeclTableKey(CtxID.Value, *NameID));
+  auto Known = Implementation->CXXMethodTable->find(*Key);
+  if (Known == Implementation->CXXMethodTable->end())
+    return std::nullopt;
+
+  return {Implementation->SwiftVersion, *Known};
+}
+
+auto APINotesReader::lookupCXXMethodImpl(
+    ContextID CtxID, llvm::StringRef Name,
+    llvm::ArrayRef<llvm::StringRef> Parameters)
+    -> VersionedInfo<CXXMethodInfo> {
+  if (!Implementation->CXXMethodTable)
+    return std::nullopt;
+
+  std::optional<FunctionTableKey> Key =
+      Implementation->getFunctionKey(CtxID.Value, Name, Parameters);
+  if (!Key)
+    return std::nullopt;
+
+  auto Known = Implementation->CXXMethodTable->find(*Key);
   if (Known == Implementation->CXXMethodTable->end())
     return std::nullopt;
 
@@ -2305,16 +2405,45 @@ auto 
APINotesReader::lookupGlobalVariable(llvm::StringRef Name,
 auto APINotesReader::lookupGlobalFunction(llvm::StringRef Name,
                                           std::optional<Context> Ctx)
     -> VersionedInfo<GlobalFunctionInfo> {
+  return lookupGlobalFunctionImpl(Name, Ctx);
+}
+
+auto APINotesReader::lookupGlobalFunction(
+    llvm::StringRef Name, llvm::ArrayRef<llvm::StringRef> Parameters,
+    std::optional<Context> Ctx) -> VersionedInfo<GlobalFunctionInfo> {
+  return lookupGlobalFunctionImpl(Name, Parameters, Ctx);
+}
+
+auto APINotesReader::lookupGlobalFunctionImpl(llvm::StringRef Name,
+                                              std::optional<Context> Ctx)
+    -> VersionedInfo<GlobalFunctionInfo> {
   if (!Implementation->GlobalFunctionTable)
     return std::nullopt;
 
-  std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
-  if (!NameID)
+  std::optional<FunctionTableKey> Key =
+      Implementation->getFunctionKey(Ctx, Name);
+  if (!Key)
     return std::nullopt;
 
-  SingleDeclTableKey Key(Ctx, *NameID);
+  auto Known = Implementation->GlobalFunctionTable->find(*Key);
+  if (Known == Implementation->GlobalFunctionTable->end())
+    return std::nullopt;
+
+  return {Implementation->SwiftVersion, *Known};
+}
+
+auto APINotesReader::lookupGlobalFunctionImpl(
+    llvm::StringRef Name, llvm::ArrayRef<llvm::StringRef> Parameters,
+    std::optional<Context> Ctx) -> VersionedInfo<GlobalFunctionInfo> {
+  if (!Implementation->GlobalFunctionTable)
+    return std::nullopt;
+
+  std::optional<FunctionTableKey> Key =
+      Implementation->getFunctionKey(Ctx, Name, Parameters);
+  if (!Key)
+    return std::nullopt;
 
-  auto Known = Implementation->GlobalFunctionTable->find(Key);
+  auto Known = Implementation->GlobalFunctionTable->find(*Key);
   if (Known == Implementation->GlobalFunctionTable->end())
     return std::nullopt;
 
diff --git a/clang/lib/APINotes/APINotesWriter.cpp 
b/clang/lib/APINotes/APINotesWriter.cpp
index 61150669d8329..0aa9812693386 100644
--- a/clang/lib/APINotes/APINotesWriter.cpp
+++ b/clang/lib/APINotes/APINotesWriter.cpp
@@ -82,8 +82,8 @@ class APINotesWriter::Implementation {
 
   /// Information about C++ methods.
   ///
-  /// Indexed by the context ID and name ID.
-  llvm::DenseMap<SingleDeclTableKey,
+  /// Indexed by the context ID, name ID, and optional parameter selector.
+  llvm::DenseMap<FunctionTableKey,
                  llvm::SmallVector<std::pair<VersionTuple, CXX...
[truncated]

``````````

</details>


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

Reply via email to