Hi,

The patch adds ASTMatchers for matching CUDA declarations.

Kindly asking for review.

Jacques

-- 
Jacques Pienaar | Platforms | [email protected] | 765-430-6883
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h	(revision 214460)
+++ include/clang/ASTMatchers/ASTMatchers.h	(working copy)
@@ -3643,6 +3643,48 @@
   return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
 }
 
+/// \brief Matches CUDA kernel call expression.
+///
+/// Example matches kernel<<<i,j>>>()
+/// \code
+///   kernel<<<i,j>>>();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+    CUDAKernelCallExpr;
+
+/// \brief Matches declaration that has CUDA device attribute.
+///
+/// Given
+/// \code
+///   __attribute__((device)) void f() { ... }
+/// \endcode
+/// matches the function declaration of f.
+AST_MATCHER(Decl, hasCudaDeviceAttr) {
+  return Node.hasAttr<clang::CUDADeviceAttr>();
+}
+
+/// \brief Matches declaration that has CUDA host attribute.
+///
+/// Given
+/// \code
+///   __attribute__((host)) void f() { ... }
+/// \endcode
+/// matches the function declaration of f.
+AST_MATCHER(Decl, hasCudaHostAttr) {
+  return Node.hasAttr<clang::CUDAHostAttr>();
+}
+
+/// \brief  Matches declaration that has CUDA global attribute.
+///
+/// Given
+/// \code
+///   __attribute__((global)) void f() { ... }
+/// \endcode
+/// matches the function declaration of f.
+AST_MATCHER(Decl, hasCudaGlobalAttr) {
+  return Node.hasAttr<clang::CUDAGlobalAttr>();
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
 
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp	(revision 214460)
+++ unittests/ASTMatchers/ASTMatchersTest.cpp	(working copy)
@@ -649,6 +649,18 @@
   EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
 }
 
+TEST(DeclarationMatcher, MatchCudaDecl) {
+  EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
+                              "void g() { f<<<1, 2>>>(); }",
+                              CUDAKernelCallExpr()));
+  EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
+                              hasCudaDeviceAttr()));
+  EXPECT_TRUE(matchesWithCuda("__attribute__((host)) void f() {}",
+                              hasCudaHostAttr()));
+  EXPECT_TRUE(matchesWithCuda("__attribute__((global)) void f() {}",
+                              hasCudaGlobalAttr()));
+}
+
 // Implements a run method that returns whether BoundNodes contains a
 // Decl bound to Id that can be dynamically cast to T.
 // Optionally checks that the check succeeded a specific number of times.
Index: unittests/ASTMatchers/ASTMatchersTest.h
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.h	(revision 214460)
+++ unittests/ASTMatchers/ASTMatchersTest.h	(working copy)
@@ -103,7 +103,73 @@
   return matchesConditionally(Code, AMatcher, false, "-std=c++11");
 }
 
+// Function based on matchesConditionally with "-x cuda" argument added and
+// small CUDA header prepended to the code string.
 template <typename T>
+testing::AssertionResult matchesConditionallyWithCuda(
+    const std::string &Code, const T &AMatcher, bool ExpectMatch,
+    llvm::StringRef CompileArg) {
+  const std::string CudaHeader =
+      "typedef unsigned int size_t;\n"
+      "#define __constant__ __attribute__((constant))\n"
+      "#define __device__ __attribute__((device))\n"
+      "#define __global__ __attribute__((global))\n"
+      "#define __host__ __attribute__((host))\n"
+      "#define __shared__ __attribute__((shared))\n"
+      "struct dim3 {"
+      "  unsigned x, y, z;"
+      "  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1)"
+      "      : x(x), y(y), z(z) {}"
+      "};"
+      "typedef struct cudaStream *cudaStream_t;"
+      "int cudaConfigureCall(dim3 gridSize, dim3 blockSize,"
+      "                      size_t sharedSize = 0,"
+      "                      cudaStream_t stream = 0);";
+
+  bool Found = false, DynamicFound = false;
+  MatchFinder Finder;
+  VerifyMatch VerifyFound(nullptr, &Found);
+  Finder.addMatcher(AMatcher, &VerifyFound);
+  VerifyMatch VerifyDynamicFound(nullptr, &DynamicFound);
+  if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
+    return testing::AssertionFailure() << "Could not add dynamic matcher";
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
+  // Some tests use typeof, which is a gnu extension.
+  std::vector<std::string> Args({"-xcuda", CompileArg});
+  if (!runToolOnCodeWithArgs(Factory->create(),
+                             CudaHeader + Code, Args)) {
+    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+  }
+  if (Found != DynamicFound) {
+    return testing::AssertionFailure() << "Dynamic match result ("
+                                       << DynamicFound
+                                       << ") does not match static result ("
+                                       << Found << ")";
+  }
+  if (!Found && ExpectMatch) {
+    return testing::AssertionFailure()
+      << "Could not find match in \"" << Code << "\"";
+  } else if (Found && !ExpectMatch) {
+    return testing::AssertionFailure()
+      << "Found unexpected match in \"" << Code << "\"";
+  }
+  return testing::AssertionSuccess();
+}
+
+template <typename T>
+testing::AssertionResult matchesWithCuda(const std::string &Code,
+                                         const T &AMatcher) {
+  return matchesConditionallyWithCuda(Code, AMatcher, true, "-std=c++11");
+}
+
+template <typename T>
+testing::AssertionResult notMatchesWithCuda(const std::string &Code,
+                                    const T &AMatcher) {
+  return matchesConditionallyWithCuda(Code, AMatcher, false, "-std=c++11");
+}
+
+template <typename T>
 testing::AssertionResult
 matchAndVerifyResultConditionally(const std::string &Code, const T &AMatcher,
                                   BoundNodesCallback *FindResultVerifier,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to