|
20 | 20 | #include "llvm/ADT/STLExtras.h"
|
21 | 21 | #include "llvm/ADT/SmallString.h"
|
22 | 22 | #include "llvm/ADT/StringExtras.h"
|
| 23 | +#include "llvm/ADT/StringMap.h" |
23 | 24 | #include "llvm/ADT/StringRef.h"
|
24 | 25 | #include "llvm/ADT/StringSet.h"
|
25 | 26 | #include "llvm/ADT/StringSwitch.h"
|
@@ -3843,11 +3844,95 @@ void EmitClangAttrSpellingListIndex(const RecordKeeper &Records,
|
3843 | 3844 | const Record &R = *I.second;
|
3844 | 3845 | std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
|
3845 | 3846 | OS << " case AT_" << I.first << ": {\n";
|
3846 |
| - for (unsigned I = 0; I < Spellings.size(); ++ I) { |
3847 |
| - OS << " if (Name == \"" << Spellings[I].name() << "\" && " |
3848 |
| - << "getSyntax() == AttributeCommonInfo::AS_" << Spellings[I].variety() |
3849 |
| - << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n" |
3850 |
| - << " return " << I << ";\n"; |
| 3847 | + |
| 3848 | + // If there are none or one spelling to check, resort to the default |
| 3849 | + // behavior of returning index as 0. |
| 3850 | + if (Spellings.size() <= 1) { |
| 3851 | + OS << " return 0;\n"; |
| 3852 | + OS << " break;\n"; |
| 3853 | + OS << " }\n"; |
| 3854 | + continue; |
| 3855 | + } |
| 3856 | + |
| 3857 | + bool HasSingleUniqueSpellingName = true; |
| 3858 | + StringMap<std::vector<const FlattenedSpelling *>> SpellingMap; |
| 3859 | + |
| 3860 | + StringRef FirstName = Spellings.front().name(); |
| 3861 | + for (const auto &S : Spellings) { |
| 3862 | + StringRef Name = S.name(); |
| 3863 | + if (Name != FirstName) |
| 3864 | + HasSingleUniqueSpellingName = false; |
| 3865 | + SpellingMap[Name].push_back(&S); |
| 3866 | + } |
| 3867 | + |
| 3868 | + // If parsed attribute has only one possible spelling name, only compare |
| 3869 | + // syntax and scope. |
| 3870 | + if (HasSingleUniqueSpellingName) { |
| 3871 | + for (const auto &[Idx, S] : enumerate(SpellingMap[FirstName])) { |
| 3872 | + OS << " if (getSyntax() == AttributeCommonInfo::AS_" << S->variety(); |
| 3873 | + |
| 3874 | + std::string ScopeStr = "AttributeCommonInfo::SC_"; |
| 3875 | + if (S->nameSpace() == "") |
| 3876 | + ScopeStr += "NONE"; |
| 3877 | + else |
| 3878 | + ScopeStr += S->nameSpace().upper(); |
| 3879 | + |
| 3880 | + OS << " && ComputedScope == " << ScopeStr << ")\n" |
| 3881 | + << " return " << Idx << ";\n"; |
| 3882 | + } |
| 3883 | + } else { |
| 3884 | + size_t Idx = 0; |
| 3885 | + for (const auto &MapEntry : SpellingMap) { |
| 3886 | + StringRef Name = MapEntry.first(); |
| 3887 | + const std::vector<const FlattenedSpelling *> &Cases = SpellingMap[Name]; |
| 3888 | + |
| 3889 | + if (Cases.size() > 1) { |
| 3890 | + // For names with multiple possible cases, emit an enclosing if such |
| 3891 | + // that the name is compared against only once. Eg: |
| 3892 | + // |
| 3893 | + // if (Name == "always_inline") { |
| 3894 | + // if (getSyntax() == AttributeCommonInfo::AS_GNU && |
| 3895 | + // ComputedScope == AttributeCommonInfo::SC_None) |
| 3896 | + // return 0; |
| 3897 | + // ... |
| 3898 | + // } |
| 3899 | + OS << " if (Name == \"" << Name << "\") {\n"; |
| 3900 | + for (const auto &S : SpellingMap[Name]) { |
| 3901 | + OS << " if (getSyntax() == AttributeCommonInfo::AS_" |
| 3902 | + << S->variety(); |
| 3903 | + std::string ScopeStr = "AttributeCommonInfo::SC_"; |
| 3904 | + if (S->nameSpace() == "") |
| 3905 | + ScopeStr += "NONE"; |
| 3906 | + else |
| 3907 | + ScopeStr += S->nameSpace().upper(); |
| 3908 | + |
| 3909 | + OS << " && ComputedScope == " << ScopeStr << ")\n" |
| 3910 | + << " return " << Idx << ";\n"; |
| 3911 | + Idx++; |
| 3912 | + } |
| 3913 | + OS << " }\n"; |
| 3914 | + } else { |
| 3915 | + // If there is only possible case for the spelling name, no need of |
| 3916 | + // enclosing if. Eg. |
| 3917 | + // |
| 3918 | + // if (Name == "__forceinline" && |
| 3919 | + // getSyntax() == AttributeCommonInfo::AS_Keyword |
| 3920 | + // && ComputedScope == AttributeCommonInfo::SC_NONE) |
| 3921 | + // return 5; |
| 3922 | + const FlattenedSpelling *S = Cases.front(); |
| 3923 | + OS << " if (Name == \"" << Name << "\""; |
| 3924 | + OS << " && getSyntax() == AttributeCommonInfo::AS_" << S->variety(); |
| 3925 | + std::string ScopeStr = "AttributeCommonInfo::SC_"; |
| 3926 | + if (S->nameSpace() == "") |
| 3927 | + ScopeStr += "NONE"; |
| 3928 | + else |
| 3929 | + ScopeStr += S->nameSpace().upper(); |
| 3930 | + |
| 3931 | + OS << " && ComputedScope == " << ScopeStr << ")\n" |
| 3932 | + << " return " << Idx << ";\n"; |
| 3933 | + Idx++; |
| 3934 | + } |
| 3935 | + } |
3851 | 3936 | }
|
3852 | 3937 |
|
3853 | 3938 | OS << " break;\n";
|
|
0 commit comments