@@ -80,10 +80,6 @@ class Util {
80
80
// / stream class.
81
81
static bool isSyclStreamType (const QualType &Ty);
82
82
83
- // / Checks whether given clang type is a full specialization of the SYCL
84
- // / item class.
85
- static bool isSyclItemType (const QualType &Ty);
86
-
87
83
// / Checks whether given clang type is a full specialization of the SYCL
88
84
// / half class.
89
85
static bool isSyclHalfType (const QualType &Ty);
@@ -103,10 +99,23 @@ class Util {
103
99
// / \param Tmpl whether the class is template instantiation or simple record
104
100
static bool isSyclType (const QualType &Ty, StringRef Name, bool Tmpl = false );
105
101
102
+ // / Checks whether given function is a standard SYCL API function with given
103
+ // / name.
104
+ // / \param FD the function being checked.
105
+ // / \param Name the function name to be checked against.
106
+ static bool isSyclFunction (const FunctionDecl *FD, StringRef Name);
107
+
106
108
// / Checks whether given clang type is a full specialization of the SYCL
107
109
// / specialization constant class.
108
110
static bool isSyclSpecConstantType (const QualType &Ty);
109
111
112
+ // Checks declaration context hierarchy.
113
+ // / \param DC the context of the item to be checked.
114
+ // / \param Scopes the declaration scopes leading from the item context to the
115
+ // / translation unit (excluding the latter)
116
+ static bool matchContext (const DeclContext *DC,
117
+ ArrayRef<Util::DeclContextDesc> Scopes);
118
+
110
119
// / Checks whether given clang type is declared in the given hierarchy of
111
120
// / declaration contexts.
112
121
// / \param Ty the clang type being checked
@@ -2736,9 +2745,8 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
2736
2745
if (!Visited.insert (FD).second )
2737
2746
continue ; // We've already seen this Decl
2738
2747
2739
- if (FD->isFunctionOrMethod () && FD->getIdentifier () &&
2740
- !FD->getName ().empty () && " this_item" == FD->getName () &&
2741
- Util::isSyclItemType (FD->getReturnType ())) {
2748
+ // Check whether this call is to sycl::this_item().
2749
+ if (Util::isSyclFunction (FD, " this_item" )) {
2742
2750
Header.setCallsThisItem (true );
2743
2751
return ;
2744
2752
}
@@ -4014,10 +4022,6 @@ bool Util::isSyclStreamType(const QualType &Ty) {
4014
4022
return isSyclType (Ty, " stream" );
4015
4023
}
4016
4024
4017
- bool Util::isSyclItemType (const QualType &Ty) {
4018
- return isSyclType (Ty, " item" , true /* Tmpl*/ );
4019
- }
4020
-
4021
4025
bool Util::isSyclHalfType (const QualType &Ty) {
4022
4026
const StringRef &Name = " half" ;
4023
4027
std::array<DeclContextDesc, 5 > Scopes = {
@@ -4064,6 +4068,21 @@ bool Util::isSyclType(const QualType &Ty, StringRef Name, bool Tmpl) {
4064
4068
return matchQualifiedTypeName (Ty, Scopes);
4065
4069
}
4066
4070
4071
+ bool Util::isSyclFunction (const FunctionDecl *FD, StringRef Name) {
4072
+ if (!FD->isFunctionOrMethod () || !FD->getIdentifier () ||
4073
+ FD->getName ().empty () || Name != FD->getName ())
4074
+ return false ;
4075
+
4076
+ const DeclContext *DC = FD->getDeclContext ();
4077
+ if (DC->isTranslationUnit ())
4078
+ return false ;
4079
+
4080
+ std::array<DeclContextDesc, 2 > Scopes = {
4081
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " cl" },
4082
+ Util::DeclContextDesc{clang::Decl::Kind::Namespace, " sycl" }};
4083
+ return matchContext (DC, Scopes);
4084
+ }
4085
+
4067
4086
bool Util::isAccessorPropertyListType (const QualType &Ty) {
4068
4087
const StringRef &Name = " accessor_property_list" ;
4069
4088
std::array<DeclContextDesc, 4 > Scopes = {
@@ -4074,21 +4093,15 @@ bool Util::isAccessorPropertyListType(const QualType &Ty) {
4074
4093
return matchQualifiedTypeName (Ty, Scopes);
4075
4094
}
4076
4095
4077
- bool Util::matchQualifiedTypeName (const QualType &Ty ,
4078
- ArrayRef<Util::DeclContextDesc> Scopes) {
4079
- // The idea: check the declaration context chain starting from the type
4096
+ bool Util::matchContext (const DeclContext *Ctx ,
4097
+ ArrayRef<Util::DeclContextDesc> Scopes) {
4098
+ // The idea: check the declaration context chain starting from the item
4080
4099
// itself. At each step check the context is of expected kind
4081
4100
// (namespace) and name.
4082
- const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl ();
4083
-
4084
- if (!RecTy)
4085
- return false ; // only classes/structs supported
4086
- const auto *Ctx = cast<DeclContext>(RecTy);
4087
4101
StringRef Name = " " ;
4088
4102
4089
4103
for (const auto &Scope : llvm::reverse (Scopes)) {
4090
4104
clang::Decl::Kind DK = Ctx->getDeclKind ();
4091
-
4092
4105
if (DK != Scope.first )
4093
4106
return false ;
4094
4107
@@ -4102,11 +4115,21 @@ bool Util::matchQualifiedTypeName(const QualType &Ty,
4102
4115
Name = cast<NamespaceDecl>(Ctx)->getName ();
4103
4116
break ;
4104
4117
default :
4105
- llvm_unreachable (" matchQualifiedTypeName : decl kind not supported" );
4118
+ llvm_unreachable (" matchContext : decl kind not supported" );
4106
4119
}
4107
4120
if (Name != Scope.second )
4108
4121
return false ;
4109
4122
Ctx = Ctx->getParent ();
4110
4123
}
4111
4124
return Ctx->isTranslationUnit ();
4112
4125
}
4126
+
4127
+ bool Util::matchQualifiedTypeName (const QualType &Ty,
4128
+ ArrayRef<Util::DeclContextDesc> Scopes) {
4129
+ const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl ();
4130
+
4131
+ if (!RecTy)
4132
+ return false ; // only classes/structs supported
4133
+ const auto *Ctx = cast<DeclContext>(RecTy);
4134
+ return Util::matchContext (Ctx, Scopes);
4135
+ }
0 commit comments