================
@@ -3841,19 +3842,110 @@ void EmitClangAttrSpellingListIndex(const RecordKeeper
&Records,
const Record &R = *I.second;
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
OS << " case AT_" << I.first << ": {\n";
- for (unsigned I = 0; I < Spellings.size(); ++ I) {
- OS << " if (Name == \"" << Spellings[I].name() << "\" && "
- << "getSyntax() == AttributeCommonInfo::AS_" << Spellings[I].variety()
- << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
- << " return " << I << ";\n";
+
+ // If there are none or one spelling to check, resort to the default
+ // behavior of returning index as 0.
+ if (Spellings.size() <= 1) {
+ OS << " return 0;\n"
+ << " break;\n"
+ << " }\n";
+ continue;
}
- OS << " break;\n";
- OS << " }\n";
+ bool HasSingleUniqueSpellingName = true;
+ StringMap<std::vector<const FlattenedSpelling *>> SpellingMap;
+
+ StringRef FirstName = Spellings.front().name();
----------------
erichkeane wrote:
This does a ton of work in a way that is pretty difficult. Really what you're
trying to find is that all of the names are the same, plus information about
the names. I think something like:
```
std::vector<StringRef> Names;
llvm::transform(Spellings, std::back_inserter(Names), [](const
FlattenedSpelling &FS) { return FS.name(); });
llvm::sort(Names);
llvm::erase(llvm::unique(Names), Names.end());
```
Would give you a lot of information that would be necessary/useful later.
First, you can check:
`Names.size() ==1` <= Means that all of the names are the same name, so you can
skip the name check entirely.
`Names.end() == std::adjacent_find(Names.begin(), Names.end(), [](StringRef
LHS, StringRef RHS){ return LHS.size() == RHS.size(); });`
If THAT is true, all you have to do is check 'size', since all of them have a
unique length.
THOUGH, you probably want to do this on a 'size' of name basis, so if you do
that in the loop of the current `FlattenedSpelling` (and add to the condition
in the `adjacent_find` that the size is the current `FS.name().size()`), if you
don't find one, you can do just the size check.
Alternatively, you can do just a `copy_if` from that based on the current
`FlattenedSpelling` name's size, which would give you the bits to tell which
actual characters to check. So something like:
```
for (const FlattenedSpelling &FS : Spellings) {
std::vector<StringRef> SameLenNames;
llvm::copy_if(Names, std::back_inserter(SameLenNames), [&](StringRef N) {
return N.size() == FS.name().size(); });
// insert print size check here
-- Since Names.size() > 1 above, we actually have to check the sizes.
THOUGH, IMO, you can be a little smarter about combining it into here too, and
only doing the copy_if that is necessary (so we only do the loop on Spellings
once).
if (SameLenNames.size() > 1) {
// if size > 1 we have to check individual characters, else we could just
do size + scope/etc
// print with just the size check.
for(StringRef SLN : SameLenNames) {
if (SLN == FS.name()) continue; // don't check same name!
auto [CurItr, OtherItr] = std::mismatch(FS.name().begin(),
FS.name().end(), SLN.begin());
// NOW you know which character to check to make sure we're unique. so
something like:
OS << "Name[" << std::distance(FS.name().begin(), CurItr) << "] == '"
<< *CurItr << "'';
}
}
}
```
THOUGH, like i said, you can probably combine the `Names.size() ==1` condition
inside of that loop as well. And probably the `adjacent_find` test can be
skipped with the loop I just wrote above.
https://github.com/llvm/llvm-project/pull/114899
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits