21
21
#include " llvm/Support/Path.h"
22
22
#include " llvm/Support/raw_ostream.h"
23
23
24
+ #include < array>
25
+
24
26
using namespace clang ;
25
27
26
28
typedef llvm::DenseMap<DeclaratorDecl *, DeclaratorDecl *> DeclMap;
@@ -40,19 +42,22 @@ enum target {
40
42
// / Various utilities.
41
43
class Util {
42
44
public:
43
- // TODO SYCL use AST infrastructure instead of string matching
44
-
45
- // / Checks whether given clang type is a sycl accessor class.
46
- static bool isSyclAccessorType (QualType Ty) {
47
- std::string Name = Ty.getCanonicalType ().getAsString ();
48
- return Name.find (" class cl::sycl::accessor" ) != std::string::npos;
49
- }
50
-
51
- // / Checks whether given clang type is a sycl stream class.
52
- static bool isSyclStreamType (QualType Ty) {
53
- std::string Name = Ty.getCanonicalType ().getAsString ();
54
- return Name == " stream" ;
55
- }
45
+ using DeclContextDesc = std::pair<clang::Decl::Kind, StringRef>;
46
+
47
+ // / Checks whether given clang type is a full specialization of the sycl
48
+ // / accessor class.
49
+ static bool isSyclAccessorType (const QualType &Ty);
50
+
51
+ // / Checks whether given clang type is the sycl stream class.
52
+ static bool isSyclStreamType (const QualType &Ty);
53
+
54
+ // / Checks whether given clang type is declared in the given hierarchy of
55
+ // / declaration contexts.
56
+ // / \param Ty the clang type being checked
57
+ // / \param Scopes the declaration scopes leading from the type to the
58
+ // / translation unit (excluding the latter)
59
+ static bool matchQualifiedTypeName (const QualType &Ty,
60
+ ArrayRef<Util::DeclContextDesc> Scopes);
56
61
};
57
62
58
63
static CXXRecordDecl *getKernelObjectType (FunctionDecl *Caller) {
@@ -1017,3 +1022,58 @@ void SYCLIntegrationHeader::endKernel() {
1017
1022
SYCLIntegrationHeader::SYCLIntegrationHeader (DiagnosticsEngine &_Diag)
1018
1023
: Diag(_Diag) {}
1019
1024
1025
+ bool Util::isSyclAccessorType (const QualType &Ty) {
1026
+ static std::array<DeclContextDesc, 3 > Scopes = {
1027
+ Util::DeclContextDesc { clang::Decl::Kind::Namespace, " cl" },
1028
+ Util::DeclContextDesc { clang::Decl::Kind::Namespace, " sycl" },
1029
+ Util::DeclContextDesc { clang::Decl::Kind::ClassTemplateSpecialization,
1030
+ " accessor" }
1031
+ };
1032
+ return matchQualifiedTypeName (Ty, Scopes);
1033
+ }
1034
+
1035
+ bool Util::isSyclStreamType (const QualType &Ty) {
1036
+ static std::array<DeclContextDesc, 3 > Scopes = {
1037
+ Util::DeclContextDesc { clang::Decl::Kind::Namespace, " cl" },
1038
+ Util::DeclContextDesc { clang::Decl::Kind::Namespace, " sycl" },
1039
+ Util::DeclContextDesc { clang::Decl::Kind::CXXRecord, " stream" }
1040
+ };
1041
+ return matchQualifiedTypeName (Ty, Scopes);
1042
+ }
1043
+
1044
+ bool Util::matchQualifiedTypeName (const QualType &Ty,
1045
+ ArrayRef<Util::DeclContextDesc> Scopes) {
1046
+ // The idea: check the declaration context chain starting from the type
1047
+ // itself. At each step check the context is of expected kind
1048
+ // (namespace) and name.
1049
+ const CXXRecordDecl *RecTy = Ty->getAsCXXRecordDecl ();
1050
+
1051
+ if (!RecTy)
1052
+ return false ; // only classes/structs supported
1053
+ const auto *Ctx = dyn_cast<DeclContext>(RecTy);
1054
+ StringRef Name = " " ;
1055
+
1056
+ for (const auto &Scope : llvm::reverse (Scopes)) {
1057
+ clang::Decl::Kind DK = Ctx->getDeclKind ();
1058
+
1059
+ if (DK != Scope.first )
1060
+ return false ;
1061
+
1062
+ switch (DK) {
1063
+ case clang::Decl::Kind::ClassTemplateSpecialization:
1064
+ // ClassTemplateSpecializationDecl inherits from CXXRecordDecl
1065
+ case clang::Decl::Kind::CXXRecord:
1066
+ Name = cast<CXXRecordDecl>(Ctx)->getName ();
1067
+ break ;
1068
+ case clang::Decl::Kind::Namespace:
1069
+ Name = cast<NamespaceDecl>(Ctx)->getName ();
1070
+ break ;
1071
+ default :
1072
+ llvm_unreachable (" matchQualifiedTypeName: decl kind not supported" );
1073
+ }
1074
+ if (Name != Scope.second )
1075
+ return false ;
1076
+ Ctx = Ctx->getParent ();
1077
+ }
1078
+ return Ctx->isTranslationUnit ();
1079
+ }
0 commit comments