Skip to content

Commit 62ce674

Browse files
authored
1 parent 27665db commit 62ce674

File tree

3 files changed

+87
-11
lines changed

3 files changed

+87
-11
lines changed

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ class AttributeCommonInfo {
6767
IgnoredAttribute,
6868
UnknownAttribute,
6969
};
70+
enum class Scope {
71+
NONE,
72+
CLANG,
73+
GNU,
74+
MSVC,
75+
OMP,
76+
HLSL,
77+
GSL,
78+
RISCV,
79+
INTEL,
80+
SYCL,
81+
CL,
82+
SYCL_DETAIL
83+
};
7084

7185
private:
7286
const IdentifierInfo *AttrName = nullptr;

clang/lib/Basic/Attributes.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include "clang/Basic/ParsedAttrInfo.h"
1818
#include "clang/Basic/TargetInfo.h"
1919

20+
#include "llvm/ADT/StringMap.h"
21+
#include "llvm/ADT/StringSwitch.h"
22+
2023
using namespace clang;
2124

2225
static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
@@ -156,13 +159,32 @@ std::string AttributeCommonInfo::getNormalizedFullName() const {
156159
return static_cast<std::string>(
157160
normalizeName(getAttrName(), getScopeName(), getSyntax()));
158161
}
162+
static AttributeCommonInfo::Scope
163+
getScopeFromNormalizedScopeName(StringRef ScopeName) {
164+
return llvm::StringSwitch<AttributeCommonInfo::Scope>(ScopeName)
165+
.Case("", AttributeCommonInfo::Scope::NONE)
166+
.Case("clang", AttributeCommonInfo::Scope::CLANG)
167+
.Case("gnu", AttributeCommonInfo::Scope::GNU)
168+
.Case("gsl", AttributeCommonInfo::Scope::GSL)
169+
.Case("hlsl", AttributeCommonInfo::Scope::HLSL)
170+
.Case("msvc", AttributeCommonInfo::Scope::MSVC)
171+
.Case("omp", AttributeCommonInfo::Scope::OMP)
172+
.Case("riscv", AttributeCommonInfo::Scope::RISCV)
173+
.Case("intel", AttributeCommonInfo::Scope::INTEL)
174+
.Case("sycl", AttributeCommonInfo::Scope::SYCL)
175+
.Case("cl", AttributeCommonInfo::Scope::CL)
176+
.Case("__sycl_detail__", AttributeCommonInfo::Scope::SYCL_DETAIL);
177+
}
159178

160179
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
161180
// Both variables will be used in tablegen generated
162181
// attribute spell list index matching code.
163182
auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
164-
StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
165-
StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
183+
StringRef ScopeName = normalizeAttrScopeName(getScopeName(), Syntax);
184+
StringRef Name = normalizeAttrName(getAttrName(), ScopeName, Syntax);
185+
186+
AttributeCommonInfo::Scope ComputedScope =
187+
getScopeFromNormalizedScopeName(ScopeName);
166188

167189
#include "clang/Sema/AttrSpellingListIndex.inc"
168190
}

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3850,19 +3850,59 @@ void EmitClangAttrSpellingListIndex(const RecordKeeper &Records,
38503850
const Record &R = *I.second;
38513851
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
38523852
OS << " case AT_" << I.first << ": {\n";
3853-
for (unsigned I = 0; I < Spellings.size(); ++ I) {
3854-
OS << " if (Name == \"" << Spellings[I].name() << "\" && "
3855-
<< "getSyntax() == AttributeCommonInfo::AS_" << Spellings[I].variety()
3856-
<< " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
3857-
<< " return " << I << ";\n";
3853+
3854+
// If there are none or one spelling to check, resort to the default
3855+
// behavior of returning index as 0.
3856+
if (Spellings.size() <= 1) {
3857+
OS << " return 0;\n"
3858+
<< " break;\n"
3859+
<< " }\n";
3860+
continue;
38583861
}
38593862

3860-
OS << " break;\n";
3861-
OS << " }\n";
3863+
std::vector<StringRef> Names;
3864+
llvm::transform(Spellings, std::back_inserter(Names),
3865+
[](const FlattenedSpelling &FS) { return FS.name(); });
3866+
llvm::sort(Names);
3867+
Names.erase(llvm::unique(Names), Names.end());
3868+
3869+
for (const auto &[Idx, FS] : enumerate(Spellings)) {
3870+
OS << " if (";
3871+
if (Names.size() > 1) {
3872+
SmallVector<StringRef, 6> SameLenNames;
3873+
StringRef FSName = FS.name();
3874+
llvm::copy_if(Names, std::back_inserter(SameLenNames),
3875+
[&](StringRef N) { return N.size() == FSName.size(); });
3876+
3877+
if (SameLenNames.size() == 1) {
3878+
OS << "Name.size() == " << FS.name().size() << " && ";
3879+
} else {
3880+
// FIXME: We currently fall back to comparing entire strings if there
3881+
// are 2 or more spelling names with the same length. This can be
3882+
// optimized to check only for the the first differing character
3883+
// between them instead.
3884+
OS << "Name == \"" << FS.name() << "\""
3885+
<< " && ";
3886+
}
3887+
}
3888+
3889+
OS << "getSyntax() == AttributeCommonInfo::AS_" << FS.variety()
3890+
<< " && ComputedScope == ";
3891+
if (FS.nameSpace() == "")
3892+
OS << "AttributeCommonInfo::Scope::NONE";
3893+
else
3894+
OS << "AttributeCommonInfo::Scope::" + FS.nameSpace().upper();
3895+
3896+
OS << ")\n"
3897+
<< " return " << Idx << ";\n";
3898+
}
3899+
3900+
OS << " break;\n"
3901+
<< " }\n";
38623902
}
38633903

3864-
OS << " }\n";
3865-
OS << " return 0;\n";
3904+
OS << " }\n"
3905+
<< " return 0;\n";
38663906
}
38673907

38683908
// Emits code used by RecursiveASTVisitor to visit attributes

0 commit comments

Comments
 (0)