llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: StoeckOverflow
<details>
<summary>Changes</summary>
This PR adds `Where.Object` selectors for C++ method API notes. They let API
notes distinguish overloads by the implicit object parameter qualifiers, such
as `const`, `volatile`, `&`, and `&&`. Static methods are unchanged
because they have no implicit object parameter.
```cpp
struct Builder {
Result build() &;
Result build() &&;
Result build() const &;
};
```
To distinguish these declarations, the selector model includes an `Object`
constraint:
```yaml
Tags:
- Name: Builder
Methods:
- Name: build
Where:
Parameters: []
Object:
Ref: lvalue
SwiftName: buildFromLValue()
- Name: build
Where:
Parameters: []
Object:
Ref: rvalue
SwiftName: buildFromRValue()
- Name: build
Where:
Parameters: []
Object:
Const: true
Ref: lvalue
SwiftName: buildFromConstLValue()
```
Changes:
- Adds `Where.Object` YAML support for C++ methods.
- Adds a shared object-selector representation with `Const`, `Volatile`, and
`Ref`.
- Extends C++ method lookup/writer keys to include object selectors.
- Applies less-constrained object selectors before more-constrained selectors
so specific notes can refine broader ones.
- Extends unmatched-selector diagnostics to track object-only and
parameter-plus-object selectors.
- Keeps global functions and static C++ methods unchanged.
Tests:
- Matching `const`, `volatile`, lvalue-ref, and rvalue-ref qualified C++
methods.
- Combined object qualifiers such as `const volatile &`, `const
&&`, and `volatile &&`.
- Coexistence of broad method notes with object-qualified notes.
- Object selector diagnostics for malformed, duplicate, and unmatched entries.
- Static methods remain unaffected because they have no implicit object
parameter.
Reviewers: @<!-- -->Xazax-hun @<!-- -->j-hui @<!-- -->egorzhdan
---
Patch is 60.26 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/216148.diff
15 Files Affected:
- (modified) clang/include/clang/APINotes/APINotesReader.h (+16-4)
- (modified) clang/include/clang/APINotes/APINotesWriter.h (+6)
- (modified) clang/include/clang/APINotes/Types.h (+137-13)
- (modified) clang/lib/APINotes/APINotesFormat.h (+59-3)
- (modified) clang/lib/APINotes/APINotesReader.cpp (+103-19)
- (modified) clang/lib/APINotes/APINotesWriter.cpp (+75-2)
- (modified) clang/lib/APINotes/APINotesYAMLCompiler.cpp (+88-44)
- (modified) clang/lib/Sema/SemaAPINotes.cpp (+123-18)
- (modified) clang/lib/Sema/SemaAPINotesInternal.h (+4-4)
- (added) clang/test/APINotes/Inputs/Headers/WhereObjectQualifiers.apinotes
(+96)
- (added) clang/test/APINotes/Inputs/Headers/WhereObjectQualifiers.h (+30)
- (modified) clang/test/APINotes/Inputs/Headers/module.modulemap (+5)
- (added)
clang/test/APINotes/Inputs/WhereObjectQualifiersDiag/APINotes.apinotes (+46)
- (added)
clang/test/APINotes/Inputs/WhereObjectQualifiersDiag/WhereObjectQualifiers.h
(+14)
- (added) clang/test/APINotes/where-object-qualifiers.cpp (+63)
``````````diff
diff --git a/clang/include/clang/APINotes/APINotesReader.h
b/clang/include/clang/APINotes/APINotesReader.h
index d74232bc334c6..99303c8a8ba02 100644
--- a/clang/include/clang/APINotes/APINotesReader.h
+++ b/clang/include/clang/APINotes/APINotesReader.h
@@ -170,6 +170,12 @@ class APINotesReader {
lookupCXXMethod(ContextID CtxID, llvm::StringRef Name,
llvm::ArrayRef<std::string> Parameters);
+ /// Look for information regarding the given C++ method with a composed
+ /// selector. Omitted selector components use the broad name-based key.
+ VersionedInfo<CXXMethodInfo>
+ lookupCXXMethod(ContextID CtxID, llvm::StringRef Name,
+ const FunctionSelector &Selector);
+
/// Build the selector key for the given C++ method.
std::optional<APINotesFunctionSelectorKey>
getCXXMethodSelectorKey(ContextID CtxID, llvm::StringRef Name);
@@ -180,6 +186,12 @@ class APINotesReader {
getCXXMethodSelectorKey(ContextID CtxID, llvm::StringRef Name,
llvm::ArrayRef<std::string> Parameters);
+ /// Build the selector key for the given C++ method with a composed
+ /// selector.
+ std::optional<APINotesFunctionSelectorKey>
+ getCXXMethodSelectorKey(ContextID CtxID, llvm::StringRef Name,
+ const FunctionSelector &Selector);
+
/// Look for information regarding the given global variable.
///
/// \param Name The name of the global variable.
@@ -218,8 +230,9 @@ class APINotesReader {
llvm::ArrayRef<std::string> Parameters,
std::optional<Context> Ctx = std::nullopt);
- /// Collect exact parameter selector keys stored by this reader.
- void collectExactFunctionParameterSelectors(
+ /// Collect selector keys stored by this reader that should be diagnosed if
+ /// unmatched.
+ void collectFunctionSelectorsForDiagnostics(
llvm::SmallVectorImpl<APINotesFunctionSelectorKey> &Selectors);
/// Reconstruct parameter selector strings for a stored exact selector key.
@@ -275,10 +288,9 @@ class APINotesReader {
private:
VersionedInfo<CXXMethodInfo> lookupCXXMethodImpl(ContextID CtxID,
llvm::StringRef Name);
- template <typename ParameterT>
VersionedInfo<CXXMethodInfo>
lookupCXXMethodImpl(ContextID CtxID, llvm::StringRef Name,
- llvm::ArrayRef<ParameterT> Parameters);
+ const FunctionSelector &Selector);
VersionedInfo<GlobalFunctionInfo>
lookupGlobalFunctionImpl(llvm::StringRef Name, std::optional<Context> Ctx);
diff --git a/clang/include/clang/APINotes/APINotesWriter.h
b/clang/include/clang/APINotes/APINotesWriter.h
index 5ed6686e1bb85..c0d07ceeb30cc 100644
--- a/clang/include/clang/APINotes/APINotesWriter.h
+++ b/clang/include/clang/APINotes/APINotesWriter.h
@@ -95,6 +95,12 @@ class APINotesWriter {
llvm::ArrayRef<llvm::StringRef> Parameters,
const CXXMethodInfo &Info, llvm::VersionTuple
SwiftVersion);
+ /// Add information about a C++ method with a composed selector. Omitted
+ /// selector components use the broad name-based key.
+ void addCXXMethod(ContextID CtxID, llvm::StringRef Name,
+ const FunctionSelector &Selector, 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.
diff --git a/clang/include/clang/APINotes/Types.h
b/clang/include/clang/APINotes/Types.h
index af989d3a1b7f0..4151e26a98b45 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -1008,19 +1008,132 @@ struct Context {
using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
+/// Describes the C++ implicit-object ref-qualifier portion of a method
+/// selector.
+enum class FunctionObjectRefQualifier : uint8_t {
+ None,
+ LValue,
+ RValue,
+};
+
+/// Describes optional constraints on a C++ method's implicit object parameter.
+struct FunctionObjectSelector {
+ std::optional<bool> Const;
+ std::optional<bool> Volatile;
+ std::optional<FunctionObjectRefQualifier> Ref;
+};
+
+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 formatAPINotesObjectSelector(FunctionObjectSelector Object)
{
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ llvm::SmallVector<std::string, 3> Parts;
+
+ if (Object.Const)
+ Parts.push_back(std::string("Const: ") +
+ (*Object.Const ? "true" : "false"));
+ if (Object.Volatile)
+ Parts.push_back(std::string("Volatile: ") +
+ (*Object.Volatile ? "true" : "false"));
+ if (Object.Ref) {
+ std::string Ref = "Ref: ";
+ switch (*Object.Ref) {
+ case FunctionObjectRefQualifier::None:
+ Ref += "none";
+ break;
+ case FunctionObjectRefQualifier::LValue:
+ Ref += "lvalue";
+ break;
+ case FunctionObjectRefQualifier::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;
+};
+
+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 += formatAPINotesObjectSelector(*Object);
+ }
+
+ return Result;
+}
+
+inline std::string
+formatAPINotesFunctionSelector(const FunctionSelector &Selector) {
+ std::optional<llvm::ArrayRef<std::string>> Parameters;
+ if (Selector.Parameters)
+ Parameters = llvm::ArrayRef<std::string>(*Selector.Parameters);
+ return formatAPINotesFunctionSelector(Parameters, Selector.Object);
+}
+
+struct FunctionTableSelectorKey {
+ std::optional<llvm::SmallVector<IdentifierID, 2>> 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<FunctionObjectSelector> objectSelector;
FunctionTableKey() : parentContextID(-1), nameID(-1) {}
- FunctionTableKey(uint32_t ParentContextID, uint32_t NameID)
- : parentContextID(ParentContextID), nameID(NameID) {}
+ FunctionTableKey(uint32_t ParentContextID, uint32_t NameID,
+ FunctionTableSelectorKey Selector = {})
+ : parentContextID(ParentContextID), nameID(NameID),
+ parameterTypeIDs(std::move(Selector.Parameters)),
+ objectSelector(Selector.Object) {}
FunctionTableKey(uint32_t ParentContextID, uint32_t NameID,
const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
@@ -1028,27 +1141,37 @@ struct FunctionTableKey {
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,
+ FunctionTableSelectorKey Selector = {})
+ : FunctionTableKey(ParentCtx ? ParentCtx->id.Value
+ : static_cast<uint32_t>(-1),
+ NameID, std::move(Selector)) {}
FunctionTableKey(std::optional<Context> ParentCtx, IdentifierID NameID,
const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
- : parentContextID(ParentCtx ? ParentCtx->id.Value
- : static_cast<uint32_t>(-1)),
- nameID(NameID) {
+ : FunctionTableKey(ParentCtx ? ParentCtx->id.Value
+ : static_cast<uint32_t>(-1),
+ NameID) {
parameterTypeIDs.emplace(ParameterTypeIDs.begin(), ParameterTypeIDs.end());
}
llvm::hash_code hashValue() const {
auto Hash = llvm::hash_combine(parentContextID, nameID,
- static_cast<bool>(parameterTypeIDs));
+ static_cast<bool>(parameterTypeIDs),
+ static_cast<bool>(objectSelector));
if (parameterTypeIDs) {
Hash = llvm::hash_combine(Hash, parameterTypeIDs->size());
for (IdentifierID TypeID : *parameterTypeIDs)
Hash = llvm::hash_combine(Hash, static_cast<unsigned>(TypeID));
}
+ if (objectSelector)
+ Hash = llvm::hash_combine(
+ Hash, objectSelector->Const.value_or(false),
+ static_cast<bool>(objectSelector->Const),
+ objectSelector->Volatile.value_or(false),
+ static_cast<bool>(objectSelector->Volatile),
+ objectSelector->Ref ? static_cast<unsigned>(*objectSelector->Ref) + 1
+ : 0);
return Hash;
}
};
@@ -1057,7 +1180,8 @@ inline bool operator==(const FunctionTableKey &LHS,
const FunctionTableKey &RHS) {
return LHS.parentContextID == RHS.parentContextID &&
LHS.nameID == RHS.nameID &&
- LHS.parameterTypeIDs == RHS.parameterTypeIDs;
+ LHS.parameterTypeIDs == RHS.parameterTypeIDs &&
+ LHS.objectSelector == RHS.objectSelector;
}
/// Stable reader-facing identity for an API notes function selector entry.
@@ -1069,7 +1193,7 @@ struct APINotesFunctionSelectorKey {
FunctionTableKey Key;
bool IsCXXMethod = false;
- APINotesFunctionSelectorKey getWithoutParameterSelector() const {
+ APINotesFunctionSelectorKey getNameOnlyKey() const {
return {FunctionTableKey(Key.parentContextID, Key.nameID), IsCXXMethod};
}
diff --git a/clang/lib/APINotes/APINotesFormat.h
b/clang/lib/APINotes/APINotesFormat.h
index 30fc8599349bf..f0ea371e3ccef 100644
--- a/clang/lib/APINotes/APINotesFormat.h
+++ b/clang/lib/APINotes/APINotesFormat.h
@@ -16,6 +16,7 @@
#include "llvm/Bitcode/BitcodeConvenience.h"
#include <optional>
+#include <utility>
namespace clang {
namespace api_notes {
@@ -28,9 +29,10 @@ 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 = 41; // 39 for BoundsSafety;
+const uint16_t VERSION_MINOR = 42; // 39 for BoundsSafety;
// 40 for UnsafeBufferUsageAttr
// 41 for FunctionTableKey parameters
+ // 42 for FunctionTableKey object selectors
const uint8_t kSwiftConforms = 1;
const uint8_t kSwiftDoesNotConform = 2;
@@ -359,8 +361,21 @@ inline bool operator==(const SingleDeclTableKey &lhs,
}
/// 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.
+/// context, the name of the declaration, and optional exact parameter/object
+/// selector data.
constexpr uint8_t FunctionKeyHasParameterSelector = 0x01;
+constexpr uint8_t FunctionKeyObjectConstPresent = 0x02;
+constexpr uint8_t FunctionKeyObjectConstValue = 0x04;
+constexpr uint8_t FunctionKeyObjectVolatilePresent = 0x08;
+constexpr uint8_t FunctionKeyObjectVolatileValue = 0x10;
+constexpr uint8_t FunctionKeyObjectRefPresent = 0x20;
+constexpr uint8_t FunctionKeyObjectRefLValue = 0x40;
+constexpr uint8_t FunctionKeyObjectRefRValue = 0x80;
+constexpr uint8_t FunctionKeyObjectSelectorMask =
+ FunctionKeyObjectConstPresent | FunctionKeyObjectConstValue |
+ FunctionKeyObjectVolatilePresent | FunctionKeyObjectVolatileValue |
+ FunctionKeyObjectRefPresent | FunctionKeyObjectRefLValue |
+ FunctionKeyObjectRefRValue;
constexpr unsigned FunctionTableKeyBaseLength =
sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint16_t);
@@ -375,10 +390,48 @@ getFunctionKeyImpl(uint32_t ParentContextID,
llvm::StringRef Name,
return FunctionTableKey(ParentContextID, *NameID);
}
+template <typename GetIdentifierFn>
+std::optional<FunctionTableKey>
+getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name,
+ FunctionObjectSelector ObjectSelector,
+ GetIdentifierFn GetIdentifier) {
+ std::optional<IdentifierID> NameID = GetIdentifier(Name);
+ if (!NameID)
+ return std::nullopt;
+
+ FunctionTableSelectorKey Selector;
+ Selector.Object = ObjectSelector;
+ return FunctionTableKey(ParentContextID, *NameID, std::move(Selector));
+}
+
+template <typename ParameterT, typename GetIdentifierFn>
+std::optional<FunctionTableKey>
+getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name,
+ llvm::ArrayRef<ParameterT> Parameters,
+ GetIdentifierFn GetIdentifier) {
+ std::optional<IdentifierID> NameID = GetIdentifier(Name);
+ if (!NameID)
+ return std::nullopt;
+
+ llvm::SmallVector<IdentifierID, 2> ParameterTypeIDs;
+ ParameterTypeIDs.reserve(Parameters.size());
+ for (const ParameterT &Parameter : Parameters) {
+ std::optional<IdentifierID> ParameterID =
+ GetIdentifier(llvm::StringRef(Parameter));
+ if (!ParameterID)
+ return std::nullopt;
+ ParameterTypeIDs.push_back(*ParameterID);
+ }
+ FunctionTableSelectorKey Selector;
+ Selector.Parameters.emplace(ParameterTypeIDs.begin(),
ParameterTypeIDs.end());
+ return FunctionTableKey(ParentContextID, *NameID, std::move(Selector));
+}
+
template <typename ParameterT, typename GetIdentifierFn>
std::optional<FunctionTableKey>
getFunctionKeyImpl(uint32_t ParentContextID, llvm::StringRef Name,
llvm::ArrayRef<ParameterT> Parameters,
+ FunctionObjectSelector ObjectSelector,
GetIdentifierFn GetIdentifier) {
std::optional<IdentifierID> NameID = GetIdentifier(Name);
if (!NameID)
@@ -393,7 +446,10 @@ getFunctionKeyImpl(uint32_t ParentContextID,
llvm::StringRef Name,
return std::nullopt;
ParameterTypeIDs.push_back(*ParameterID);
}
- return FunctionTableKey(ParentContextID, *NameID, ParameterTypeIDs);
+ FunctionTableSelectorKey Selector;
+ Selector.Parameters.emplace(ParameterTypeIDs.begin(),
ParameterTypeIDs.end());
+ Selector.Object = ObjectSelector;
+ return FunctionTableKey(ParentContextID, *NameID, std::move(Selector));
}
} // namespace api_notes
diff --git a/clang/lib/APINotes/APINotesReader.cpp
b/clang/lib/APINotes/APINotesReader.cpp
index aad597d93d9ee..ab06d75826d1a 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -72,14 +72,47 @@ static FunctionTableKey readFunctionTableKey(const uint8_t
*Data,
ParameterTypeIDs.push_back(
endian::readNext<uint32_t, llvm::endianness::little>(Data));
- assert((FunctionKeyFlags & ~FunctionKeyHasParameterSelector) == 0 &&
- "Unexpected function table key flags");
+ if (FunctionKeyFlags & FunctionKeyObjectRefLValue)
+ assert(!(FunctionKeyFlags & FunctionKeyObjectRefRValue) &&
+ "Unexpected function table key ref qualifier flags");
+ assert(((FunctionKeyFlags & FunctionKeyObjectConstValue) == 0 ||
+ (FunctionKeyFlags & FunctionKeyObjectConstPresent)) &&
+ "Function table key const value requires presence flag");
+ assert(((FunctionKeyFlags & FunctionKeyObjectVolatileValue) == 0 ||
+ (FunctionKeyFlags & FunctionKeyObjectVolatilePresent)) &&
+ "Function table key volatile value requires presence flag");
+ assert(((FunctionKeyFlags &
+ (FunctionKeyObjectRefLValue | FunctionKeyObjectRefRValue)) == 0 ||
+ (FunctionKeyFlags & FunctionKeyObjectRefPresent)) &&
+ "Function table key ref value requires presence flag");
+ std::optional<FunctionObjectSelector> ObjectSelector;
+ if (FunctionKeyFlags & FunctionKeyObjectSelectorMask) {
+ FunctionObjectSelector Selector;
+ if (FunctionKeyFlags & FunctionKeyObjectConstPresent)
+ Selector.Const = (FunctionKeyFlags & FunctionKeyObjectConstValue) != 0;
+ if (FunctionKeyFlags & FunctionKeyObjectVolatilePresent)
+ Selector.Volatile =
+ (FunctionKeyFlags & FunctionKeyObjectVolatileValue) != 0;
+ if (FunctionKeyFlags & FunctionKeyObjectRefPresent) {
+ if (FunctionKeyFlags & FunctionKeyObjectRefLValue)
+ Selector.Ref = FunctionObjectRefQualifier::LValue;
+ else if (FunctionKeyFlags & FunctionKeyObjectRefRValue)
+ Selector.Ref = FunctionObjectRefQualifier::RValue;
+ else
+ Selector.Ref = FunctionObjectRefQualifier::None;
+ }
+ ObjectSelector = Selector;
+ }
+
+ FunctionTableSelectorKey Selector;
if (FunctionKeyFlags & FunctionKeyHasParameterSelector)
- return {CtxID, NameID, ParameterTypeIDs};
-
- assert(ParameterTypeIDs.empty() &&
- "Broad function table key should not store parameters");
- return {CtxID, NameID};
+ Selector.Parameters.emplace(ParameterTypeIDs.begin(),
+ ParameterTypeIDs.end());
+ else
+ assert(ParameterTypeIDs.empty() &&
+ "Broad function table key should not store parameters");
+ Selector.Object = ObjectSelector;
+ return FunctionTableKey(CtxID, NameID, std::move(Selector));
}
/// An on-disk hash table whose data is versioned based on the Swift version.
@@ -844,10 +877,10 @@ class APINotesReader::Implementation {
/// the ID is unknown.
std::optional<llvm::StringRef> getIdentifierString(IdentifierID ID);
- /// Collect exact parameter selector keys stored in the given function-like
- /// table.
+ /// Collect selector keys stored in the given function-like table that
+ /// should be diagnosed if unmatched.
template <typename TableT>
- void collectExactFunctionParameterSelectors(
+ void collectFunctionSelectorsForDiagnostics(
TableT &Table,
llvm::SmallVectorImpl<APINotesFunctionSelectorKey> &Selectors);
@@ -880,11 +913,17 @@ class APINotesReader::Implementation {
getFunctionKey(uint32_t ParentContextID, llvm::StringRef Name,
llvm::ArrayRef<ParameterT> Parameters);
std::optional<FunctionTableKey>
+ getFunctionKey(uint32_t ParentContextID, llvm::StringRef Name,
+ const FunctionSelector &Selector);
+ std::optional<FunctionTableKey>
getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name);
template <typename ParameterT>
std::optional<FunctionTableKey>
getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name,
llvm::ArrayRef<ParameterT> Parameters);
+ std::optional<FunctionTableKey>
+ getFunctionKey(std::optional<Context> ParentContext, llvm::StringRef Name,
+ const FunctionSelector &Selector);
llvm::Error readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t>
&Scratch);
@@ -944,7 +983,7 @@ APINotesReader::Implementation...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/216148
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits