Index: clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp =================================================================== --- clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp +++ clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "KernelNameRestrictionCheck.h" #include "StructPackAlignCheck.h" using namespace clang::ast_matchers; @@ -20,6 +21,8 @@ class AlteraModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "altera-kernel-name-restriction"); CheckFactories.registerCheck( "altera-struct-pack-align"); } Index: clang-tools-extra/clang-tidy/altera/CMakeLists.txt =================================================================== --- clang-tools-extra/clang-tidy/altera/CMakeLists.txt +++ clang-tools-extra/clang-tidy/altera/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangTidyAlteraModule AlteraTidyModule.cpp + KernelNameRestrictionCheck.cpp StructPackAlignCheck.cpp LINK_LIBS Index: clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.h =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.h @@ -0,0 +1,35 @@ +//===--- 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 "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace altera { + +/// Finds kernel files and include directives whose filename is `kernel.cl`, +/// `Verilog.cl`, or `VHDL.cl`. +/// +/// 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-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp @@ -0,0 +1,96 @@ +//===--- 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" +#include +#include + +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. + StringRef Filename; // Filename as a string. + }; + std::vector IncludeDirectives; + + ClangTidyCheck &Check; + const SourceManager &SM; +}; + +} // namespace + +void KernelNameRestrictionCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + PP->addPPCallbacks( + std::make_unique(*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 (const IncludeDirective &ID : IncludeDirectives) { + StringRef FilePath = ID.Filename; + StringRef 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. + const FileEntry *Entry = SM.getFileEntryForID(SM.getMainFileID()); + StringRef FilePath = Entry->getName(); + StringRef 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-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -79,6 +79,12 @@ New checks ^^^^^^^^^^ +- New :doc:`altera-kernel-name-restriction + ` check. + + Finds kernel files and include directives whose filename is `kernel.cl`, + `Verilog.cl`, or `VHDL.cl`. + - New :doc:`altera-struct-pack-align ` check. Index: clang-tools-extra/docs/clang-tidy/checks/altera-kernel-name-restriction.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clang-tidy/checks/altera-kernel-name-restriction.rst @@ -0,0 +1,15 @@ +.. 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. + +Based on the `Guidelines for Naming the Kernel` section in the +`Intel FPGA SDK for OpenCL Pro Edition: Programming Guide +`_. Index: clang-tools-extra/docs/clang-tidy/checks/list.rst =================================================================== --- clang-tools-extra/docs/clang-tidy/checks/list.rst +++ clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -30,6 +30,7 @@ `abseil-time-comparison `_, "Yes" `abseil-time-subtraction `_, "Yes" `abseil-upgrade-duration-conversions `_, "Yes" + `altera-kernel-name-restriction `_, `altera-struct-pack-align `_, `android-cloexec-accept `_, "Yes" `android-cloexec-accept4 `_, Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl @@ -0,0 +1 @@ +const int KERNELINT2 = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl @@ -0,0 +1 @@ +const int VHDLINT = 3; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl @@ -0,0 +1 @@ +const int VERILOGINT = 2; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h @@ -0,0 +1 @@ +const int KERNELINT3 = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl @@ -0,0 +1 @@ +const int KERNELINT = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl @@ -0,0 +1 @@ +const int OTHERVERILOGINT = 2; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl @@ -0,0 +1 @@ +const int OTHERDIRVHDLINT = 3; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl @@ -0,0 +1 @@ +const int OTHERTHINGINT = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl @@ -0,0 +1 @@ +const int SOMEDIRKERNELINT = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl @@ -0,0 +1 @@ +const int SOMEKERNELINT = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl @@ -0,0 +1 @@ +const int SOMEDIRVERILOGINT = 2; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h @@ -0,0 +1 @@ +const int THINGINT = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl @@ -0,0 +1 @@ +const int VERILOGINT2 = 2; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h @@ -0,0 +1 @@ +const int VERILOGINT3 = 2; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h @@ -0,0 +1 @@ +const int VHDLINT3 = 3; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL @@ -0,0 +1 @@ +const int VHDLINT2 = 3; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl @@ -0,0 +1 @@ +const int VHDLNUMBERTWOINT = 3; Index: clang-tools-extra/test/clang-tidy/checkers/altera-kernel-name-restriction.cpp =================================================================== --- /dev/null +++ clang-tools-extra/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: llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn +++ llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn @@ -13,6 +13,7 @@ ] sources = [ "AlteraTidyModule.cpp", + "KernelNameRestrictionCheck.cpp", "StructPackAlignCheck.cpp", ] }