diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -58,6 +58,7 @@ add_subdirectory(cert) add_subdirectory(concurrency) add_subdirectory(cppcoreguidelines) +add_subdirectory(cuda) add_subdirectory(darwin) add_subdirectory(fuchsia) add_subdirectory(google) @@ -85,6 +86,7 @@ clangTidyCERTModule clangTidyConcurrencyModule clangTidyCppCoreGuidelinesModule + clangTidyCudaModule clangTidyDarwinModule clangTidyFuchsiaModule clangTidyGoogleModule diff --git a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h --- a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h +++ b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h @@ -55,6 +55,11 @@ static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination = CppCoreGuidelinesModuleAnchorSource; +// This anchor is used to force the linker to link the CudaModule. +extern volatile int CudaModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED CudaModuleAnchorDestination = + CudaModuleAnchorSource; + // This anchor is used to force the linker to link the DarwinModule. extern volatile int DarwinModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED DarwinModuleAnchorDestination = diff --git a/clang-tools-extra/clang-tidy/cuda/CMakeLists.txt b/clang-tools-extra/clang-tidy/cuda/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cuda/CMakeLists.txt @@ -0,0 +1,15 @@ +add_clang_library(clangTidyCudaModule + CudaTidyModule.cpp + LINK_LIBS + clangTidy + clangTidyUtils + ) + +clang_target_link_libraries(clangTidyAlteraModule + PRIVATE + clangAnalysis + clangAST + clangASTMatchers + clangBasic + clangLex + ) diff --git a/clang-tools-extra/clang-tidy/cuda/CudaTidyModule.cpp b/clang-tools-extra/clang-tidy/cuda/CudaTidyModule.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/clang-tidy/cuda/CudaTidyModule.cpp @@ -0,0 +1,36 @@ +//===--- CudaTidyModule.cpp - clang-tidy --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" +#include "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace cuda { + +class CudaModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {} +}; + +// Register the CudaTidyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add + X("cuda-module", "Adds Cuda-related lint checks."); + +} // namespace cuda + +// This anchor is used to force the linker to link in the generated object file +// and thus register the CudaModule. +volatile int CudaModuleAnchorSource = 0; + +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -96,6 +96,8 @@ Improvements to clang-tidy -------------------------- +- Introduce the cuda module for checks specific to CUDA code. + New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -16,6 +16,7 @@ clang-analyzer/* concurrency/* cppcoreguidelines/* + cuda/* darwin/* fuchsia/* google/* diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -67,6 +67,7 @@ ``concurrency-`` Checks related to concurrent programming (including threads, fibers, coroutines, etc.). ``cppcoreguidelines-`` Checks related to C++ Core Guidelines. +``cuda-`` Checks related to CUDA best practices. ``darwin-`` Checks related to Darwin coding conventions. ``fuchsia-`` Checks related to Fuchsia coding conventions. ``google-`` Checks related to Google coding conventions. diff --git a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py --- a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py +++ b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py @@ -93,7 +93,7 @@ file_name_with_extension = self.assume_file_name or self.input_file_name _, extension = os.path.splitext(file_name_with_extension) - if extension not in ['.c', '.hpp', '.m', '.mm']: + if extension not in ['.c', '.cu', '.hpp', '.m', '.mm']: extension = '.cpp' self.temp_file_name = self.temp_file_name + extension @@ -115,9 +115,14 @@ self.clang_extra_args = ['-fobjc-abi-version=2', '-fobjc-arc', '-fblocks'] + \ self.clang_extra_args - if extension in ['.cpp', '.hpp', '.mm']: + if extension in ['.cpp', '.cu', '.hpp', '.mm']: self.clang_extra_args.append('-std=' + self.std) + # Tests should not rely on a certain cuda headers and library version + # being available on the machine + if extension == '.cu': + self.clang_extra_args.extend(["--no-cuda-version-check", "-nocudalib", "-nocudainc"]) + # Tests should not rely on STL being available, and instead provide mock # implementations of relevant APIs. self.clang_extra_args.append('-nostdinc++') diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/cuda/cuda.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/cuda/cuda.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/cuda/cuda.h @@ -0,0 +1,28 @@ +/* Minimal declarations for CUDA support. Testing purposes only. */ + +#include "../stddef.h" + +#define __constant__ __attribute__((constant)) +#define __device__ __attribute__((device)) +#define __global__ __attribute__((global)) +#define __host__ __attribute__((host)) +#define __shared__ __attribute__((shared)) + +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; +typedef enum cudaError {} cudaError_t; +extern "C" int cudaConfigureCall(dim3 gridSize, dim3 blockSize, + size_t sharedSize = 0, + cudaStream_t stream = 0); +extern "C" int __cudaPushCallConfiguration(dim3 gridSize, dim3 blockSize, + size_t sharedSize = 0, + cudaStream_t stream = 0); +extern "C" cudaError_t cudaLaunchKernel(const void *func, dim3 gridDim, + dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream); + +extern "C" __device__ int printf(const char*, ...); diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/stddef.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/stddef.h new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/stddef.h @@ -0,0 +1,14 @@ +//===--- stddef.h - Stub header for tests -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _STDDEF_H_ +#define _STDDEF_H_ + +using size_t = long long unsigned; + +#endif // _STDDEF_H_