1010#define LLVM_CLANG_LIB_APINOTES_APINOTESFORMAT_H
1111
1212#include " clang/APINotes/Types.h"
13+ #include " llvm/ADT/ArrayRef.h"
1314#include " llvm/ADT/PointerEmbeddedInt.h"
15+ #include " llvm/ADT/SmallVector.h"
1416#include " llvm/Bitcode/BitcodeConvenience.h"
1517
18+ #include < optional>
19+
1620namespace clang {
1721namespace api_notes {
1822// / Magic number for API notes files.
@@ -24,8 +28,9 @@ const uint16_t VERSION_MAJOR = 0;
2428// / API notes file minor version number.
2529// /
2630// / When the format changes IN ANY WAY, this number should be incremented.
27- const uint16_t VERSION_MINOR = 40 ; // 39 for BoundsSafety;
31+ const uint16_t VERSION_MINOR = 41 ; // 39 for BoundsSafety;
2832 // 40 for UnsafeBufferUsageAttr
33+ // 41 for FunctionTableKey parameters
2934
3035const uint8_t kSwiftConforms = 1 ;
3136const uint8_t kSwiftDoesNotConform = 2 ;
@@ -354,6 +359,91 @@ inline bool operator==(const SingleDeclTableKey &lhs,
354359 return lhs.parentContextID == rhs.parentContextID && lhs.nameID == rhs.nameID ;
355360}
356361
362+ // / A stored C or C++ function declaration, represented by the ID of its parent
363+ // / context, the name of the declaration, and optional exact parameter types.
364+ constexpr uint8_t FunctionKeyHasParameterSelector = 0x01 ;
365+ constexpr unsigned FunctionTableKeyBaseLength =
366+ sizeof (uint32_t ) + sizeof (uint32_t ) + sizeof (uint8_t ) + sizeof (uint16_t );
367+
368+ struct FunctionTableKey {
369+ uint32_t parentContextID;
370+ uint32_t nameID;
371+ std::optional<llvm::SmallVector<IdentifierID, 2 >> parameterTypeIDs;
372+
373+ FunctionTableKey () : parentContextID(-1 ), nameID(-1 ) {}
374+
375+ FunctionTableKey (uint32_t ParentContextID, uint32_t NameID)
376+ : parentContextID(ParentContextID), nameID(NameID) {}
377+
378+ FunctionTableKey (uint32_t ParentContextID, uint32_t NameID,
379+ const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
380+ : parentContextID(ParentContextID), nameID(NameID) {
381+ parameterTypeIDs.emplace (ParameterTypeIDs.begin (), ParameterTypeIDs.end ());
382+ }
383+
384+ FunctionTableKey (std::optional<Context> ParentCtx, IdentifierID NameID)
385+ : parentContextID(ParentCtx ? ParentCtx->id.Value
386+ : static_cast <uint32_t >(-1 )),
387+ nameID (NameID) {}
388+
389+ FunctionTableKey (std::optional<Context> ParentCtx, IdentifierID NameID,
390+ const llvm::SmallVectorImpl<IdentifierID> &ParameterTypeIDs)
391+ : parentContextID(ParentCtx ? ParentCtx->id.Value
392+ : static_cast <uint32_t >(-1 )),
393+ nameID(NameID) {
394+ parameterTypeIDs.emplace (ParameterTypeIDs.begin (), ParameterTypeIDs.end ());
395+ }
396+
397+ llvm::hash_code hashValue () const {
398+ auto Hash = llvm::hash_combine (parentContextID, nameID,
399+ static_cast <bool >(parameterTypeIDs));
400+ if (parameterTypeIDs) {
401+ Hash = llvm::hash_combine (Hash, parameterTypeIDs->size ());
402+ for (IdentifierID TypeID : *parameterTypeIDs)
403+ Hash = llvm::hash_combine (Hash, static_cast <unsigned >(TypeID));
404+ }
405+ return Hash;
406+ }
407+ };
408+
409+ template <typename GetIdentifierFn>
410+ std::optional<FunctionTableKey>
411+ getFunctionKeyImpl (uint32_t ParentContextID, llvm::StringRef Name,
412+ GetIdentifierFn GetIdentifier) {
413+ std::optional<IdentifierID> NameID = GetIdentifier (Name);
414+ if (!NameID)
415+ return std::nullopt ;
416+
417+ return FunctionTableKey (ParentContextID, *NameID);
418+ }
419+
420+ template <typename GetIdentifierFn>
421+ std::optional<FunctionTableKey>
422+ getFunctionKeyImpl (uint32_t ParentContextID, llvm::StringRef Name,
423+ llvm::ArrayRef<llvm::StringRef> Parameters,
424+ GetIdentifierFn GetIdentifier) {
425+ std::optional<IdentifierID> NameID = GetIdentifier (Name);
426+ if (!NameID)
427+ return std::nullopt ;
428+
429+ llvm::SmallVector<IdentifierID, 2 > ParameterTypeIDs;
430+ ParameterTypeIDs.reserve (Parameters.size ());
431+ for (llvm::StringRef Parameter : Parameters) {
432+ std::optional<IdentifierID> ParameterID = GetIdentifier (Parameter);
433+ if (!ParameterID)
434+ return std::nullopt ;
435+ ParameterTypeIDs.push_back (*ParameterID);
436+ }
437+ return FunctionTableKey (ParentContextID, *NameID, ParameterTypeIDs);
438+ }
439+
440+ inline bool operator ==(const FunctionTableKey &lhs,
441+ const FunctionTableKey &rhs) {
442+ return lhs.parentContextID == rhs.parentContextID &&
443+ lhs.nameID == rhs.nameID &&
444+ lhs.parameterTypeIDs == rhs.parameterTypeIDs ;
445+ }
446+
357447} // namespace api_notes
358448} // namespace clang
359449
@@ -401,6 +491,18 @@ template <> struct DenseMapInfo<clang::api_notes::SingleDeclTableKey> {
401491 }
402492};
403493
494+ template <> struct DenseMapInfo <clang::api_notes::FunctionTableKey> {
495+ static unsigned
496+ getHashValue (const clang::api_notes::FunctionTableKey &value) {
497+ return value.hashValue ();
498+ }
499+
500+ static bool isEqual (const clang::api_notes::FunctionTableKey &lhs,
501+ const clang::api_notes::FunctionTableKey &rhs) {
502+ return lhs == rhs;
503+ }
504+ };
505+
404506} // namespace llvm
405507
406508#endif
0 commit comments