Skip to content

Commit 77dd693

Browse files
[SYCL] Replace hardcoded namespaces with attribute (#6674)
Namespaces were hardcoded and used in compiler to check for various SYCL types including accessors, spec_constants, etc. This patch implements an attribute to uniquely identify the types instead. Attribute argument is an Identifier which denotes each type. E.g. __attribute__((sycl_type(accessor)) is used to mark accessor class. The attribute has been implemented as with an accepted list of arguments via EnumArg. The attribute definition should be updated to support any new types. The attribute takes 1 argument. Fixes: #5186 Signed-off-by: Elizabeth Andrews <[email protected]>
1 parent 57aabe7 commit 77dd693

21 files changed

+260
-308
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,23 @@ def SYCLSpecialClass: InheritableAttr {
12811281
let Documentation = [SYCLSpecialClassDocs];
12821282
}
12831283

1284+
def SYCLType: InheritableAttr {
1285+
let Spellings = [CXX11<"__sycl_detail__", "sycl_type">];
1286+
let Subjects = SubjectList<[CXXRecord, Enum], ErrorDiag>;
1287+
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1288+
let Args = [EnumArgument<"Type", "SYCLType",
1289+
["accessor", "local_accessor", "spec_constant",
1290+
"specialization_id", "kernel_handler", "buffer_location",
1291+
"no_alias", "accessor_property_list", "group",
1292+
"private_memory", "aspect"],
1293+
["accessor", "local_accessor", "spec_constant",
1294+
"specialization_id", "kernel_handler", "buffer_location",
1295+
"no_alias", "accessor_property_list", "group",
1296+
"private_memory", "aspect"]>];
1297+
// Only used internally by SYCL implementation
1298+
let Documentation = [InternalOnly];
1299+
}
1300+
12841301
def SYCLDeviceHas : InheritableAttr {
12851302
let Spellings = [CXX11<"sycl", "device_has">];
12861303
let Subjects = SubjectList<[Function], ErrorDiag>;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4098,6 +4098,8 @@ def warn_transparent_union_attribute_zero_fields : Warning<
40984098
def warn_attribute_type_not_supported : Warning<
40994099
"%0 attribute argument not supported: %1">,
41004100
InGroup<IgnoredAttributes>;
4101+
def err_attribute_argument_not_supported : Error<
4102+
"%0 attribute argument %1 is not supported">;
41014103
def warn_attribute_unknown_visibility : Warning<"unknown visibility %0">,
41024104
InGroup<IgnoredAttributes>;
41034105
def warn_attribute_protected_visibility :

clang/include/clang/Sema/Sema.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10858,6 +10858,9 @@ class Sema final {
1085810858
ReqdWorkGroupSizeAttr *
1085910859
MergeReqdWorkGroupSizeAttr(Decl *D, const ReqdWorkGroupSizeAttr &A);
1086010860

10861+
SYCLTypeAttr *MergeSYCLTypeAttr(Decl *D, const AttributeCommonInfo &CI,
10862+
SYCLTypeAttr::SYCLType TypeName);
10863+
1086110864
/// Only called on function definitions; if there is a MSVC #pragma optimize
1086210865
/// in scope, consider changing the function's attributes based on the
1086310866
/// optimization list passed to the pragma.
@@ -13546,12 +13549,16 @@ class Sema final {
1354613549
const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl();
1354713550
if (!RecTy)
1354813551
return false;
13552+
13553+
if (RecTy->hasAttr<AttrTy>())
13554+
return true;
13555+
1354913556
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RecTy)) {
1355013557
ClassTemplateDecl *Template = CTSD->getSpecializedTemplate();
1355113558
if (CXXRecordDecl *RD = Template->getTemplatedDecl())
1355213559
return RD->hasAttr<AttrTy>();
1355313560
}
13554-
return RecTy->hasAttr<AttrTy>();
13561+
return false;
1355513562
}
1355613563

1355713564
private:

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,6 +2918,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
29182918
NewAttr = S.MergeSYCLDeviceHasAttr(D, *A);
29192919
else if (const auto *A = dyn_cast<SYCLUsesAspectsAttr>(Attr))
29202920
NewAttr = S.MergeSYCLUsesAspectsAttr(D, *A);
2921+
else if (const auto *A = dyn_cast<SYCLTypeAttr>(Attr))
2922+
NewAttr = S.MergeSYCLTypeAttr(D, *A, A->getType());
29212923
else if (const auto *A = dyn_cast<SYCLIntelPipeIOAttr>(Attr))
29222924
NewAttr = S.MergeSYCLIntelPipeIOAttr(D, *A);
29232925
else if (const auto *A = dyn_cast<SYCLIntelMaxWorkGroupSizeAttr>(Attr))

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10426,46 +10426,15 @@ static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
1042610426
D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
1042710427
}
1042810428

10429-
static constexpr std::pair<Decl::Kind, StringRef>
10430-
MakeDeclContextDesc(Decl::Kind K, StringRef SR) {
10431-
return std::pair<Decl::Kind, StringRef>{K, SR};
10432-
}
10433-
10434-
// FIXME: Refactor Util class in SemaSYCL.cpp to avoid following
10435-
// code duplication.
1043610429
bool isDeviceAspectType(const QualType Ty) {
1043710430
const EnumType *ET = Ty->getAs<EnumType>();
1043810431
if (!ET)
1043910432
return false;
1044010433

10441-
std::array<std::pair<Decl::Kind, StringRef>, 3> Scopes = {
10442-
MakeDeclContextDesc(Decl::Kind::Namespace, "sycl"),
10443-
MakeDeclContextDesc(Decl::Kind::Namespace, "_V1"),
10444-
MakeDeclContextDesc(Decl::Kind::Enum, "aspect")};
10445-
10446-
const auto *Ctx = cast<DeclContext>(ET->getDecl());
10447-
StringRef Name = "";
10448-
10449-
for (const auto &Scope : llvm::reverse(Scopes)) {
10450-
Decl::Kind DK = Ctx->getDeclKind();
10451-
if (DK != Scope.first)
10452-
return false;
10434+
if (const auto *Attr = ET->getDecl()->getAttr<SYCLTypeAttr>())
10435+
return Attr->getType() == SYCLTypeAttr::aspect;
1045310436

10454-
switch (DK) {
10455-
case Decl::Kind::Enum:
10456-
Name = cast<EnumDecl>(Ctx)->getName();
10457-
break;
10458-
case Decl::Kind::Namespace:
10459-
Name = cast<NamespaceDecl>(Ctx)->getName();
10460-
break;
10461-
default:
10462-
llvm_unreachable("isDeviceAspectType: decl kind not supported");
10463-
}
10464-
if (Name != Scope.second)
10465-
return false;
10466-
Ctx = Ctx->getParent();
10467-
}
10468-
return Ctx->isTranslationUnit();
10437+
return false;
1046910438
}
1047010439

1047110440
SYCLDeviceHasAttr *Sema::MergeSYCLDeviceHasAttr(Decl *D,
@@ -10590,6 +10559,39 @@ static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1059010559
handleSimpleAttribute<SYCLKernelAttr>(S, D, AL);
1059110560
}
1059210561

10562+
SYCLTypeAttr *Sema::MergeSYCLTypeAttr(Decl *D, const AttributeCommonInfo &CI,
10563+
SYCLTypeAttr::SYCLType TypeName) {
10564+
if (const auto *ExistingAttr = D->getAttr<SYCLTypeAttr>()) {
10565+
if (ExistingAttr->getType() != TypeName) {
10566+
Diag(ExistingAttr->getLoc(), diag::err_duplicate_attribute)
10567+
<< ExistingAttr;
10568+
Diag(CI.getLoc(), diag::note_previous_attribute);
10569+
}
10570+
// Do not add duplicate attribute
10571+
return nullptr;
10572+
}
10573+
return ::new (Context) SYCLTypeAttr(Context, CI, TypeName);
10574+
}
10575+
10576+
static void handleSYCLTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
10577+
if (!AL.isArgIdent(0)) {
10578+
S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
10579+
<< AL << AANT_ArgumentIdentifier;
10580+
return;
10581+
}
10582+
10583+
IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
10584+
SYCLTypeAttr::SYCLType Type;
10585+
10586+
if (!SYCLTypeAttr::ConvertStrToSYCLType(II->getName(), Type)) {
10587+
S.Diag(AL.getLoc(), diag::err_attribute_argument_not_supported) << AL << II;
10588+
return;
10589+
}
10590+
10591+
if (SYCLTypeAttr *NewAttr = S.MergeSYCLTypeAttr(D, AL, Type))
10592+
D->addAttr(NewAttr);
10593+
}
10594+
1059310595
static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
1059410596
if (!cast<VarDecl>(D)->hasGlobalStorage()) {
1059510597
S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
@@ -11142,6 +11144,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
1114211144
case ParsedAttr::AT_SYCLSpecialClass:
1114311145
handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);
1114411146
break;
11147+
case ParsedAttr::AT_SYCLType:
11148+
handleSYCLTypeAttr(S, D, AL);
11149+
break;
1114511150
case ParsedAttr::AT_SYCLDevice:
1114611151
handleSYCLDeviceAttr(S, D, AL);
1114711152
break;

0 commit comments

Comments
 (0)