27struct RISCVExtensionVersion {
32struct RISCVSupportedExtension {
43 {
"i", RISCVExtensionVersion{2, 0}},
44 {
"e", RISCVExtensionVersion{1, 9}},
45 {
"m", RISCVExtensionVersion{2, 0}},
46 {
"a", RISCVExtensionVersion{2, 0}},
47 {
"f", RISCVExtensionVersion{2, 0}},
48 {
"d", RISCVExtensionVersion{2, 0}},
49 {
"c", RISCVExtensionVersion{2, 0}},
51 {
"h", RISCVExtensionVersion{1, 0}},
53 {
"zihintpause", RISCVExtensionVersion{2, 0}},
55 {
"zfhmin", RISCVExtensionVersion{1, 0}},
56 {
"zfh", RISCVExtensionVersion{1, 0}},
58 {
"zfinx", RISCVExtensionVersion{1, 0}},
59 {
"zdinx", RISCVExtensionVersion{1, 0}},
60 {
"zhinxmin", RISCVExtensionVersion{1, 0}},
61 {
"zhinx", RISCVExtensionVersion{1, 0}},
63 {
"zba", RISCVExtensionVersion{1, 0}},
64 {
"zbb", RISCVExtensionVersion{1, 0}},
65 {
"zbc", RISCVExtensionVersion{1, 0}},
66 {
"zbs", RISCVExtensionVersion{1, 0}},
68 {
"zbkb", RISCVExtensionVersion{1, 0}},
69 {
"zbkc", RISCVExtensionVersion{1, 0}},
70 {
"zbkx", RISCVExtensionVersion{1, 0}},
71 {
"zknd", RISCVExtensionVersion{1, 0}},
72 {
"zkne", RISCVExtensionVersion{1, 0}},
73 {
"zknh", RISCVExtensionVersion{1, 0}},
74 {
"zksed", RISCVExtensionVersion{1, 0}},
75 {
"zksh", RISCVExtensionVersion{1, 0}},
76 {
"zkr", RISCVExtensionVersion{1, 0}},
77 {
"zkn", RISCVExtensionVersion{1, 0}},
78 {
"zks", RISCVExtensionVersion{1, 0}},
79 {
"zkt", RISCVExtensionVersion{1, 0}},
80 {
"zk", RISCVExtensionVersion{1, 0}},
82 {
"zmmul", RISCVExtensionVersion{1, 0}},
84 {
"v", RISCVExtensionVersion{1, 0}},
85 {
"zvl32b", RISCVExtensionVersion{1, 0}},
86 {
"zvl64b", RISCVExtensionVersion{1, 0}},
87 {
"zvl128b", RISCVExtensionVersion{1, 0}},
88 {
"zvl256b", RISCVExtensionVersion{1, 0}},
89 {
"zvl512b", RISCVExtensionVersion{1, 0}},
90 {
"zvl1024b", RISCVExtensionVersion{1, 0}},
91 {
"zvl2048b", RISCVExtensionVersion{1, 0}},
92 {
"zvl4096b", RISCVExtensionVersion{1, 0}},
93 {
"zvl8192b", RISCVExtensionVersion{1, 0}},
94 {
"zvl16384b", RISCVExtensionVersion{1, 0}},
95 {
"zvl32768b", RISCVExtensionVersion{1, 0}},
96 {
"zvl65536b", RISCVExtensionVersion{1, 0}},
97 {
"zve32x", RISCVExtensionVersion{1, 0}},
98 {
"zve32f", RISCVExtensionVersion{1, 0}},
99 {
"zve64x", RISCVExtensionVersion{1, 0}},
100 {
"zve64f", RISCVExtensionVersion{1, 0}},
101 {
"zve64d", RISCVExtensionVersion{1, 0}},
103 {
"zicbom", RISCVExtensionVersion{1, 0}},
104 {
"zicboz", RISCVExtensionVersion{1, 0}},
105 {
"zicbop", RISCVExtensionVersion{1, 0}},
107 {
"svnapot", RISCVExtensionVersion{1, 0}},
108 {
"svpbmt", RISCVExtensionVersion{1, 0}},
109 {
"svinval", RISCVExtensionVersion{1, 0}},
112 {
"xtheadvdot", RISCVExtensionVersion{1, 0}},
113 {
"xventanacondops", RISCVExtensionVersion{1, 0}},
117 {
"zihintntl", RISCVExtensionVersion{0, 2}},
119 {
"zca", RISCVExtensionVersion{1, 0}},
120 {
"zcb", RISCVExtensionVersion{1, 0}},
121 {
"zcd", RISCVExtensionVersion{1, 0}},
122 {
"zcf", RISCVExtensionVersion{1, 0}},
123 {
"zvfh", RISCVExtensionVersion{0, 1}},
124 {
"zawrs", RISCVExtensionVersion{1, 0}},
125 {
"ztso", RISCVExtensionVersion{0, 1}},
129 return Ext.consume_front(
"experimental-");
141 "Already guarded by if-statement in ::parseArchString");
143 int Pos = Ext.size() - 1;
144 while (Pos > 0 &&
isDigit(Ext[Pos]))
146 if (Pos > 0 && Ext[Pos] ==
'p' &&
isDigit(Ext[Pos - 1])) {
148 while (Pos > 0 &&
isDigit(Ext[Pos]))
158 bool operator()(
const RISCVSupportedExtension &ExtInfo) {
159 return ExtInfo.Name ==
Ext;
164static std::optional<RISCVExtensionVersion>
170 auto ExtensionInfoIterator =
llvm::find_if(ExtInfo, FindByName(ExtName));
172 if (ExtensionInfoIterator == ExtInfo.end()) {
175 return ExtensionInfoIterator->Version;
180void RISCVISAInfo::addExtension(
StringRef ExtName,
unsigned MajorVersion,
181 unsigned MinorVersion) {
183 Ext.ExtName = ExtName.
str();
184 Ext.MajorVersion = MajorVersion;
185 Ext.MinorVersion = MinorVersion;
186 Exts[ExtName.
str()] =
Ext;
190 if (Ext.startswith(
"sx"))
191 return "non-standard supervisor-level extension";
192 if (Ext.startswith(
"s"))
193 return "standard supervisor-level extension";
194 if (Ext.startswith(
"x"))
195 return "non-standard user-level extension";
196 if (Ext.startswith(
"z"))
197 return "standard user-level extension";
202 if (Ext.startswith(
"sx"))
204 if (Ext.startswith(
"s"))
206 if (Ext.startswith(
"x"))
208 if (Ext.startswith(
"z"))
213static std::optional<RISCVExtensionVersion>
220 return ExtIterator->Version;
238 unsigned MinorVersion) {
239 auto FindByNameAndVersion = [=](
const RISCVSupportedExtension &ExtInfo) {
240 return ExtInfo.Name == Ext && (MajorVersion == ExtInfo.Version.Major) &&
241 (MinorVersion == ExtInfo.Version.Minor);
253 return Exts.count(Ext.str()) != 0;
283 assert(ExtName.length() >= 2);
287 char ExtClass = ExtName[0];
306 return (HighOrder << 8) + LowOrder;
312 const std::string &RHS) {
313 size_t LHSLen =
LHS.length();
314 size_t RHSLen =
RHS.length();
315 if (LHSLen == 1 && RHSLen != 1)
318 if (LHSLen != 1 && RHSLen == 1)
321 if (LHSLen == 1 && RHSLen == 1)
328 if (LHSRank != RHSRank)
329 return LHSRank < RHSRank;
336 std::vector<StringRef> &Features,
338 bool AddAllExtensions)
const {
339 for (
auto const &Ext : Exts) {
346 Features.push_back(StrAlloc(
"+experimental-" + ExtName));
348 Features.push_back(StrAlloc(
"+" + ExtName));
351 if (AddAllExtensions) {
353 if (Exts.count(Ext.Name))
355 Features.push_back(StrAlloc(
Twine(
"-") + Ext.Name));
359 if (Exts.count(Ext.Name))
361 Features.push_back(StrAlloc(
Twine(
"-experimental-") + Ext.Name));
372 unsigned &Minor,
unsigned &ConsumeLength,
373 bool EnableExperimentalExtension,
374 bool ExperimentalExtensionVersionCheck) {
379 MajorStr = In.take_while(
isDigit);
380 In = In.substr(MajorStr.
size());
382 if (!MajorStr.
empty() && In.consume_front(
"p")) {
383 MinorStr = In.take_while(
isDigit);
384 In = In.substr(MajorStr.
size() + MinorStr.
size() - 1);
387 if (MinorStr.
empty()) {
390 "minor version number missing after 'p' for extension '" + Ext +
"'");
397 "Failed to parse major version number for extension '" + Ext +
"'");
402 "Failed to parse minor version number for extension '" + Ext +
"'");
404 ConsumeLength = MajorStr.
size();
406 if (!MinorStr.
empty())
407 ConsumeLength += MinorStr.
size() + 1 ;
412 if (Ext.size() > 1 && In.size()) {
414 "multi-character extensions must be separated by underscores";
420 if (!EnableExperimentalExtension) {
421 std::string
Error =
"requires '-menable-experimental-extensions' for "
422 "experimental extension '" +
427 if (ExperimentalExtensionVersionCheck &&
430 "experimental extension requires explicit version number `" +
435 auto SupportedVers = *ExperimentalExtension;
436 if (ExperimentalExtensionVersionCheck &&
437 (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
438 std::string
Error =
"unsupported version number " + MajorStr.
str();
439 if (!MinorStr.
empty())
441 Error +=
" for experimental extension '" + Ext.str() +
442 "' (this compiler supports " + utostr(SupportedVers.Major) +
443 "." + utostr(SupportedVers.Minor) +
")";
456 Major = DefaultVersion->Major;
457 Minor = DefaultVersion->Minor;
467 std::string
Error =
"unsupported version number " + std::string(MajorStr);
468 if (!MinorStr.
empty())
470 Error +=
" for extension '" + Ext.str() +
"'";
476 const std::vector<std::string> &Features) {
477 assert(XLen == 32 || XLen == 64);
478 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
480 for (
auto &Feature : Features) {
482 bool Experimental =
false;
483 assert(ExtName.
size() > 1 && (ExtName[0] ==
'+' || ExtName[0] ==
'-'));
484 bool Add = ExtName[0] ==
'+';
487 auto ExtensionInfos = Experimental
490 auto ExtensionInfoIterator =
495 if (ExtensionInfoIterator == ExtensionInfos.end())
499 ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
500 ExtensionInfoIterator->Version.Minor);
502 ISAInfo->Exts.erase(ExtName.
str());
510 bool ExperimentalExtensionVersionCheck,
511 bool IgnoreUnknown) {
515 "string must be lowercase");
522 "string must begin with rv32{i,e,g} or rv64{i,g}");
525 unsigned XLen = HasRV64 ? 64 : 32;
526 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
531 char Baseline = Arch[4];
537 "first letter should be 'e', 'i' or 'g'");
543 "standard user-level extension 'e' requires 'rv32'");
564 OtherExts = Exts.
substr(Pos);
565 Exts = Exts.
substr(0, Pos);
568 unsigned Major, Minor, ConsumeLength;
570 ConsumeLength, EnableExperimentalExtension,
571 ExperimentalExtensionVersionCheck))
574 if (Baseline ==
'g') {
578 for (
const auto *Ext : {
"i",
"m",
"a",
"f",
"d"})
580 ISAInfo->addExtension(Ext, Version->Major, Version->Minor);
585 ISAInfo->addExtension(std::string(1, Baseline), Major, Minor);
594 auto StdExtsItr = StdExts.
begin();
595 auto StdExtsEnd = StdExts.
end();
597 I += 1 + ConsumeLength;
605 while (StdExtsItr != StdExtsEnd && *StdExtsItr !=
C)
608 if (StdExtsItr == StdExtsEnd) {
614 "standard user-level extension not given in canonical order '%c'",
619 "invalid standard user-level extension '%c'",
C);
626 unsigned Major, Minor, ConsumeLength;
627 if (std::next(
I) !=
E)
628 Next = std::string(std::next(
I),
E);
630 ConsumeLength, EnableExperimentalExtension,
631 ExperimentalExtensionVersionCheck)) {
634 GoToNextExt(
I, ConsumeLength);
645 GoToNextExt(
I, ConsumeLength);
649 "unsupported standard user-level extension '%c'",
652 ISAInfo->addExtension(std::string(1,
C), Major, Minor);
656 GoToNextExt(
I, ConsumeLength);
672 OtherExts.
split(Split,
'_');
675 std::array<StringRef, 4> Prefix{
"z",
"x",
"s",
"sx"};
676 auto I = Prefix.begin();
677 auto E = Prefix.end();
678 if (Split.size() > 1 || Split[0] !=
"") {
682 "extension name missing after separator '_'");
694 "invalid extension prefix '" + Ext +
"'");
705 "%s not given in canonical order '%s'",
706 Desc.
str().c_str(), Ext.str().c_str());
709 if (!IgnoreUnknown &&
Name.size() ==
Type.size()) {
711 "%s name missing after '%s'",
712 Desc.
str().c_str(),
Type.str().c_str());
715 unsigned Major, Minor, ConsumeLength;
717 EnableExperimentalExtension,
718 ExperimentalExtensionVersionCheck)) {
729 Desc.
str().c_str(),
Name.str().c_str());
732 ISAInfo->addExtension(
Name, Major, Minor);
739 for (
auto Ext : AllExts) {
743 Desc.
str().c_str(), Ext.str().c_str());
750Error RISCVISAInfo::checkDependency() {
751 bool IsRv32 = XLen == 32;
752 bool HasE = Exts.count(
"e") != 0;
753 bool HasD = Exts.count(
"d") != 0;
754 bool HasF = Exts.count(
"f") != 0;
755 bool HasZfinx = Exts.count(
"zfinx") != 0;
756 bool HasZdinx = Exts.count(
"zdinx") != 0;
757 bool HasVector = Exts.count(
"zve32x") != 0;
758 bool HasZve32f = Exts.count(
"zve32f") != 0;
759 bool HasZve64d = Exts.count(
"zve64d") != 0;
760 bool HasZvl = MinVLen != 0;
765 "standard user-level extension 'e' requires 'rv32'");
773 "d requires f extension to also be specified");
775 if (HasZve32f && !HasF && !HasZfinx)
778 "zve32f requires f or zfinx extension to also be specified");
780 if (HasZve64d && !HasD && !HasZdinx)
783 "zve64d requires d or zdinx extension to also be specified");
785 if (Exts.count(
"zvfh") && !Exts.count(
"zfh") && !Exts.count(
"zfhmin") &&
786 !Exts.count(
"zhinx") && !Exts.count(
"zhinxmin"))
789 "zvfh requires zfh, zfhmin, zhinx or zhinxmin extension to also be "
792 if (HasZvl && !HasVector)
795 "zvl*b requires v or zve* extension to also be specified");
828 "zkne",
"zknd",
"zknh"};
877void RISCVISAInfo::updateImplication() {
878 bool HasE = Exts.count(
"e") != 0;
879 bool HasI = Exts.count(
"i") != 0;
883 if (!HasE && !HasI) {
893 for (
auto const &Ext : Exts)
896 while (!WorkList.
empty()) {
900 for (
const char *ImpliedExt :
I->Exts) {
901 if (WorkList.
count(ImpliedExt))
903 if (Exts.count(ImpliedExt))
907 WorkList.
insert(ImpliedExt);
924void RISCVISAInfo::updateCombination() {
925 bool IsNewCombine =
false;
927 IsNewCombine =
false;
929 auto CombineExt = CombineIntoExt.CombineExt;
930 auto RequiredExts = CombineIntoExt.RequiredExts;
933 bool IsAllRequiredFeatureExist =
true;
934 for (
const char *Ext : RequiredExts)
936 if (IsAllRequiredFeatureExist) {
942 }
while (IsNewCombine);
945void RISCVISAInfo::updateFLen() {
950 else if (Exts.count(
"f"))
954void RISCVISAInfo::updateMinVLen() {
955 for (
auto const &Ext : Exts) {
961 MinVLen = std::max(MinVLen, ZvlLen);
966void RISCVISAInfo::updateMaxELen() {
968 for (
auto const &Ext : Exts) {
972 if (ExtName.
back() ==
'f')
973 MaxELenFp = std::max(MaxELenFp, 32u);
974 if (ExtName.
back() ==
'd')
975 MaxELenFp = std::max(MaxELenFp, 64u);
979 MaxELen = std::max(MaxELen, ZveELen);
988 Arch <<
"rv" << XLen;
990 ListSeparator LS(
"_");
991 for (
auto const &Ext : Exts) {
993 auto ExtInfo = Ext.second;
994 Arch << LS << ExtName;
995 Arch << ExtInfo.MajorVersion <<
"p" << ExtInfo.MinorVersion;
1002 std::vector<std::string> FeatureVector;
1003 for (
auto const &Ext : Exts) {
1004 std::string ExtName = Ext.first;
1008 ?
"+experimental-" + ExtName
1010 FeatureVector.push_back(Feature);
1012 return FeatureVector;
1017 ISAInfo->updateImplication();
1018 ISAInfo->updateCombination();
1019 ISAInfo->updateFLen();
1020 ISAInfo->updateMinVLen();
1021 ISAInfo->updateMaxELen();
1023 if (
Error Result = ISAInfo->checkDependency())
1024 return std::move(Result);
1025 return std::move(ISAInfo);
1035 }
else if (XLen == 64) {
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::optional< std::vector< StOtherPiece > > Other
static const char * ImpliedExtsZvl8192b[]
static const char * ImpliedExtsZks[]
static const char * ImpliedExtsZcb[]
static const char * ImpliedExtsZvl2048b[]
static const char * ImpliedExtsXTHeadVdot[]
static StringRef getExtensionTypeDesc(StringRef Ext)
static const char * ImpliedExtsZvl512b[]
static const char * ImpliedExtsZve32x[]
static constexpr ImpliedExtsEntry ImpliedExts[]
static const char * ImpliedExtsZve32f[]
static const char * ImpliedExtsZvl4096b[]
static const RISCVSupportedExtension SupportedExtensions[]
static int singleLetterExtensionRank(char Ext)
static const char * ImpliedExtsZvfh[]
static const char * ImpliedExtsZvl65536b[]
static const char * ImpliedExtsZve64f[]
static const char * ImpliedExtsZvl1024b[]
static const char * ImpliedExtsZhinx[]
static constexpr CombinedExtsEntry CombineIntoExts[]
static const char * ImpliedExtsZve64x[]
static const char * ImpliedExtsZk[]
static const RISCVSupportedExtension SupportedExperimentalExtensions[]
static int multiLetterExtensionRank(const std::string &ExtName)
static const char * ImpliedExtsZvl256b[]
static StringRef getExtensionType(StringRef Ext)
static const char * ImpliedExtsZfhmin[]
static std::optional< RISCVExtensionVersion > isExperimentalExtension(StringRef Ext)
static const char * ImpliedExtsZkn[]
static bool stripExperimentalPrefix(StringRef &Ext)
static std::optional< RISCVExtensionVersion > findDefaultVersion(StringRef ExtName)
static const char * ImpliedExtsZvl64b[]
static const char * ImpliedExtsZvl16384b[]
static const char * ImpliedExtsZvl128b[]
static constexpr StringLiteral AllStdExts
static const char * ImpliedExtsZfh[]
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)
static const char * ImpliedExtsZvl32768b[]
static const char * ImpliedExtsZdinx[]
static size_t findFirstNonVersionCharacter(StringRef Ext)
static const char * ImpliedExtsZhinxmin[]
static const char * ImpliedExtsV[]
static const char * ImpliedExtsZve64d[]
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
static bool isSupportedExtensionFeature(StringRef Ext)
bool hasExtension(StringRef Ext) const
static bool compareExtension(const std::string &LHS, const std::string &RHS)
std::string toString() const
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > postProcessAndChecking(std::unique_ptr< RISCVISAInfo > &&ISAInfo)
std::vector< std::string > toFeatureVector() const
StringRef computeDefaultABI() const
static bool isSupportedExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatures(unsigned XLen, const std::vector< std::string > &Features)
Parse RISCV ISA info from feature vector.
void toFeatures(std::vector< StringRef > &Features, llvm::function_ref< StringRef(const Twine &)> StrAlloc, bool AddAllExtensions) const
Convert RISCV ISA info to a feature vector.
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true, bool IgnoreUnknown=false)
Parse RISCV ISA info from arch string.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
A SetVector that performs no allocations if smaller than a certain size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
char back() const
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
bool startswith(StringRef Prefix) const
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static constexpr size_t npos
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
void consumeError(Error Err)
Consume a Error without doing anything.
ArrayRef< const char * > RequiredExts
ArrayRef< const char * > Exts
bool operator<(const ImpliedExtsEntry &Other) const
bool operator<(StringRef Other) const