ffrankies created this revision. ffrankies added reviewers: alexfh, hokein, aaron.ballman. ffrankies added projects: clang-tools-extra, clang, LLVM. Herald added subscribers: mgehre, ormris, arphaman, xazax.hun, Anastasia, mgorny.
This lint check is part of the FLOCL (FPGA Linters for OpenCL) project out of the Synergy Lab at Virginia Tech. FLOCL is a set of lint checks aimed at FPGA developers who code in OpenCL. The altera kernel name restriction check finds kernel files and include directives whose filename is "kernel.cl", "Verilog.cl", or "VHDL.cl". Such kernel file names cause the Altera Offline Compiler to generate intermediate design files that have the same names as certain internal files, which leads to a compilation error. As per the "Guidelines for Naming the Kernel" section in the "Intel FPGA SDK for OpenCL Pro Edition: Programming Guide." Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D72218 Files: clang-tidy/CMakeLists.txt clang-tidy/ClangTidyForceLinker.h clang-tidy/altera/AlteraTidyModule.cpp clang-tidy/altera/CMakeLists.txt clang-tidy/altera/KernelNameRestrictionCheck.cpp clang-tidy/altera/KernelNameRestrictionCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/altera-kernel-name-restriction.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/index.rst test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl test/clang-tidy/checkers/altera-kernel-name-restriction.cpp
Index: test/clang-tidy/checkers/altera-kernel-name-restriction.cpp =================================================================== --- /dev/null +++ test/clang-tidy/checkers/altera-kernel-name-restriction.cpp @@ -0,0 +1,42 @@ +// RUN: %check_clang_tidy %s altera-kernel-name-restriction %t -- -- -I%S/Inputs/altera-kernel-name-restriction + +// These are the banned kernel filenames, and should trigger warnings +#include "kernel.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "Verilog.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "VHDL.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] + +// The warning should be triggered regardless of capitalization +#include "KERNEL.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "vERILOG.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "vhdl.CL" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] + +// The warning should be triggered if the names are within a directory +#include "some/dir/kernel.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "somedir/verilog.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] +#include "otherdir/vhdl.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: The imported kernel source file is named 'kernel.cl','Verilog.cl', or 'VHDL.cl', which could cause compilation errors. [altera-kernel-name-restriction] + +// There are no FIX-ITs for the altera-kernel-name-restriction lint check + +// The following include directives shouldn't trigger the warning +#include "otherthing.cl" +#include "thing.h" + +// It doesn't make sense to have kernel.h, verilog.h, or vhdl.h as filenames without the corresponding .cl files, +// but the Altera Programming Guide doesn't explicitly forbid it +#include "kernel.h" +#include "verilog.h" +#include "vhdl.h" + +// The files can still have the forbidden names in them, so long as they're not the entire file name +#include "some_kernel.cl" +#include "other_Verilog.cl" +#include "vhdl_number_two.cl" Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl @@ -0,0 +1 @@ +const int VHDLNUMBERTWOINT = 3; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h @@ -0,0 +1 @@ +const int VHDLINT3 = 3; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL @@ -0,0 +1 @@ +const int VHDLINT2 = 3; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h @@ -0,0 +1 @@ +const int VERILOGINT3 = 2; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl @@ -0,0 +1 @@ +const int VERILOGINT2 = 2; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h @@ -0,0 +1 @@ +const int THINGINT = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl @@ -0,0 +1 @@ +const int SOMEDIRVERILOGINT = 2; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl @@ -0,0 +1 @@ +const int SOMEKERNELINT = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl @@ -0,0 +1 @@ +const int SOMEDIRKERNELINT = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl @@ -0,0 +1 @@ +const int OTHERTHINGINT = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl @@ -0,0 +1 @@ +const int OTHERDIRVHDLINT = 3; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl @@ -0,0 +1 @@ +const int OTHERVERILOGINT = 2; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h @@ -0,0 +1 @@ +const int KERNELINT3 = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl @@ -0,0 +1 @@ +const int KERNELINT = 1; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl @@ -0,0 +1 @@ +const int VERILOGINT = 2; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl @@ -0,0 +1 @@ +const int VHDLINT = 3; Index: test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl =================================================================== --- /dev/null +++ test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl @@ -0,0 +1 @@ +const int KERNELINT2 = 1; Index: docs/clang-tidy/index.rst =================================================================== --- docs/clang-tidy/index.rst +++ docs/clang-tidy/index.rst @@ -59,6 +59,7 @@ ====================== ========================================================= ``abseil-`` Checks related to Abseil library. ``android-`` Checks related to Android. +``altera-`` Checks related to OpenCL programming for FPGAs. ``boost-`` Checks related to Boost library. ``bugprone-`` Checks that target bugprone code constructs. ``cert-`` Checks related to CERT Secure Coding Guidelines. Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -22,6 +22,7 @@ abseil-time-comparison abseil-time-subtraction abseil-upgrade-duration-conversions + altera-kernel-name-restriction android-cloexec-accept android-cloexec-accept4 android-cloexec-creat Index: docs/clang-tidy/checks/altera-kernel-name-restriction.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/altera-kernel-name-restriction.rst @@ -0,0 +1,14 @@ +.. title:: clang-tidy - altera-kernel-name-restriction + +altera-kernel-name-restriction +============================ + +Finds kernel files and include directives whose filename is "kernel.cl", +"Verilog.cl", or "VHDL.cl". + +Such kernel file names cause the offline compiler to generate intermediate +design files that have the same names as certain internal files, which +leads to a compilation error. + +As per the "Guidelines for Naming the Kernel" section in the "Intel FPGA SDK +for OpenCL Pro Edition: Programming Guide." Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -67,6 +67,18 @@ Improvements to clang-tidy -------------------------- +- New :doc:`altera <clang-tidy/modules/altera>` module. + + Includes checks related to OpenCL for FPGA coding guidelines, based on the + `Altera SDK for OpenCL: Best Practices Guide + <https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf>`_. + +- New :doc:`altera-kernel-name-restriction + <clang-tidy/checks/altera-kernel-name-restriction>` check. + + Checks for cases where the kernel source file is named "kernel.cl", + "Verilog.cl", or "VHDL.cl". + - New :doc:`bugprone-dynamic-static-initializers <clang-tidy/checks/bugprone-dynamic-static-initializers>` check. Index: clang-tidy/altera/KernelNameRestrictionCheck.h =================================================================== --- /dev/null +++ clang-tidy/altera/KernelNameRestrictionCheck.h @@ -0,0 +1,36 @@ +//===--- KernelNameRestrictionCheck.h - clang-tidy --------------*- 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 LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_KERNEL_NAME_RESTRICTION_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_KERNEL_NAME_RESTRICTION_CHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace altera { + +/// Flags kernel files that are named kernel.cl, Verilog.cl or VHDL.cl as +/// warnings, since this may lead to intermediate files being generated that +/// have the same names as certain internal files, leading to compiler errors. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/altera-kernel-name-restriction.html +class KernelNameRestrictionCheck : public ClangTidyCheck { +public: + KernelNameRestrictionCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; +}; + +} // namespace altera +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_KERNEL_NAME_RESTRICTION_CHECK_H Index: clang-tidy/altera/KernelNameRestrictionCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/altera/KernelNameRestrictionCheck.cpp @@ -0,0 +1,95 @@ +//===--- KernelNameRestrictionCheck.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 "KernelNameRestrictionCheck.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace altera { + +namespace { +class KernelNameRestrictionPPCallbacks : public PPCallbacks { +public: + explicit KernelNameRestrictionPPCallbacks(ClangTidyCheck &Check, + const SourceManager &SM) + : Check(Check), SM(SM) {} + + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FileNameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; + + void EndOfMainFile() override; + +private: + struct IncludeDirective { + SourceLocation Loc; // Location in the include directive. + std::string Filename; // Filename as a string. + }; + std::vector<IncludeDirective> IncludeDirectives; + + ClangTidyCheck &Check; + const SourceManager &SM; +}; +} // namespace + +void KernelNameRestrictionCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + PP->addPPCallbacks( + std::make_unique<KernelNameRestrictionPPCallbacks>(*this, SM)); +} + +void KernelNameRestrictionPPCallbacks::InclusionDirective( + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, + SrcMgr::CharacteristicKind FileType) { + IncludeDirective ID = {HashLoc, FileName}; + IncludeDirectives.push_back(std::move(ID)); +} + +void KernelNameRestrictionPPCallbacks::EndOfMainFile() { + if (IncludeDirectives.empty()) + return; + + // Check included files for restricted names. + for (IncludeDirective &ID : IncludeDirectives) { + auto FilePath = StringRef(ID.Filename); + auto FileName = FilePath.substr(FilePath.find_last_of("/\\") + 1); + if (FileName.equals_lower("kernel.cl") || + FileName.equals_lower("verilog.cl") || + FileName.equals_lower("vhdl.cl")) { + Check.diag(ID.Loc, + "The imported kernel source file is named 'kernel.cl'," + "'Verilog.cl', or 'VHDL.cl', which could cause compilation " + "errors."); + } + } + + // Check main file for restricted names. + auto Entry = SM.getFileEntryForID(SM.getMainFileID()); + StringRef FilePath = Entry->getName(); + auto FileName = FilePath.substr(FilePath.find_last_of("/\\") + 1); + if (FileName.equals_lower("kernel.cl") || + FileName.equals_lower("verilog.cl") || FileName.equals_lower("vhdl.cl")) { + Check.diag(SM.getLocForStartOfFile(SM.getMainFileID()), + "Naming your OpenCL kernel source file 'kernel.cl', 'Verilog.cl'" + ", or 'VHDL.cl' could cause compilation errors."); + } +} + +} // namespace altera +} // namespace tidy +} // namespace clang Index: clang-tidy/altera/CMakeLists.txt =================================================================== --- /dev/null +++ clang-tidy/altera/CMakeLists.txt @@ -0,0 +1,15 @@ +set(LLVM_LINK_COMPONENTS support) + +add_clang_library(clangTidyAlteraModule + AlteraTidyModule.cpp + KernelNameRestrictionCheck.cpp + + LINK_LIBS + clangAnalysis + clangAST + clangASTMatchers + clangBasic + clangLex + clangTidy + clangTidyUtils + ) Index: clang-tidy/altera/AlteraTidyModule.cpp =================================================================== --- /dev/null +++ clang-tidy/altera/AlteraTidyModule.cpp @@ -0,0 +1,39 @@ +//===--- AlteraTidyModule.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 "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" +#include "KernelNameRestrictionCheck.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace altera { + +class AlteraModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck<KernelNameRestrictionCheck>( + "altera-kernel-name-restriction"); + } +}; + +} // namespace altera + +// Register the AlteraTidyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add<altera::AlteraModule> + X("altera-module", "Adds Altera FPGA OpenCL lint checks."); + +// This anchor is used to force the linker to link in the generated object file +// and thus register the AlteraModule. +volatile int AlteraModuleAnchorSource = 0; + +} // namespace tidy +} // namespace clang Index: clang-tidy/ClangTidyForceLinker.h =================================================================== --- clang-tidy/ClangTidyForceLinker.h +++ clang-tidy/ClangTidyForceLinker.h @@ -25,6 +25,11 @@ static int LLVM_ATTRIBUTE_UNUSED AbseilModuleAnchorDestination = AbseilModuleAnchorSource; +// This anchor is used to force the linker to link the AlteraModule. +extern volatile int AlteraModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED AlteraModuleAnchorDestination = + AlteraModuleAnchorSource; + // This anchor is used to force the linker to link the BoostModule. extern volatile int BoostModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED BoostModuleAnchorDestination = Index: clang-tidy/CMakeLists.txt =================================================================== --- clang-tidy/CMakeLists.txt +++ clang-tidy/CMakeLists.txt @@ -41,6 +41,7 @@ # If you add a check, also add it to ClangTidyForceLinker.h in this directory. add_subdirectory(android) add_subdirectory(abseil) +add_subdirectory(altera) add_subdirectory(boost) add_subdirectory(bugprone) add_subdirectory(cert) @@ -65,6 +66,7 @@ set(ALL_CLANG_TIDY_CHECKS clangTidyAndroidModule clangTidyAbseilModule + clangTidyAlteraModule clangTidyBoostModule clangTidyBugproneModule clangTidyCERTModule
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits