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 *) 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,107 @@ +//===--- 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: + /// Returns true if the name of the file with path FilePath is 'kernel.cl', + /// 'verilog.cl', or 'vhdl.cl'. The file name check is case insensitive. + bool FileNameIsRestricted(StringRef FilePath); + + 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 *) { + PP->addPPCallbacks( + std::make_unique(*this, SM)); +} + +void KernelNameRestrictionPPCallbacks::InclusionDirective( + SourceLocation HashLoc, const Token &, StringRef FileName, bool, + CharSourceRange, const FileEntry *, StringRef, StringRef, const Module *, + SrcMgr::CharacteristicKind) { + IncludeDirective ID = {HashLoc, FileName}; + IncludeDirectives.push_back(std::move(ID)); +} + +bool KernelNameRestrictionPPCallbacks::FileNameIsRestricted( + StringRef FileName) { + return FileName.equals_lower("kernel.cl") || + FileName.equals_lower("verilog.cl") || + FileName.equals_lower("vhdl.cl"); +} + +void KernelNameRestrictionPPCallbacks::EndOfMainFile() { + + // Check main file for restricted names. + const FileEntry *Entry = SM.getFileEntryForID(SM.getMainFileID()); + StringRef FileName = llvm::sys::path::filename(Entry->getName()); + if (FileNameIsRestricted(FileName)) + Check.diag(SM.getLocForStartOfFile(SM.getMainFileID()), + "compiling '%0' may cause additional compilation errors due " + "to the name of the kernel source file; consider renaming the " + "included kernel source file") + << FileName; + + if (IncludeDirectives.empty()) + return; + + // Check included files for restricted names. + for (const IncludeDirective &ID : IncludeDirectives) { + StringRef FileName = llvm::sys::path::filename(ID.FileName); + if (FileNameIsRestricted(FileName)) + Check.diag(ID.Loc, + "including '%0' may cause additional compilation errors due " + "to the name of the kernel source file; consider renaming the " + "included kernel source file") + << FileName; + } +} + +} // 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 @@ -85,6 +85,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`. The check is case insensitive. + +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/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/foo.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/kernel.cl/foo.h @@ -0,0 +1 @@ +int SOME_KERNEL_FOO_INT = 0; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/verilog.cl/foo.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/verilog.cl/foo.h @@ -0,0 +1 @@ +int SOME_VERILOG_FOO_INT = 0; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/vhdl.cl/foo.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/vhdl.cl/foo.h @@ -0,0 +1 @@ +int SOME_VHDL_FOO_INT = 0; 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/uppercase/KERNEL.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/uppercase/KERNEL.cl @@ -0,0 +1 @@ +const int KERNELINT2 = 1; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/uppercase/VHDL.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/uppercase/VHDL.cl @@ -0,0 +1 @@ +const int VHDLINT = 3; Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/uppercase/vERILOG.cl =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/uppercase/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,55 @@ +// RUN: %check_clang_tidy %s altera-kernel-name-restriction %t -- -- -I%S/Inputs/altera-kernel-name-restriction +// RUN: %check_clang_tidy -check-suffix=UPPERCASE %s altera-kernel-name-restriction %t -- -- -I%S/Inputs/altera-kernel-name-restriction/uppercase -DUPPERCASE + +#ifdef UPPERCASE +// The warning should be triggered regardless of capitalization +#include "KERNEL.cl" +// CHECK-MESSAGES-UPPERCASE: :[[@LINE-1]]:1: warning: including 'KERNEL.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "vERILOG.cl" +// CHECK-MESSAGES-UPPERCASE: :[[@LINE-1]]:1: warning: including 'vERILOG.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "VHDL.cl" +// CHECK-MESSAGES-UPPERCASE: :[[@LINE-1]]:1: warning: including 'VHDL.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#else +// These are the banned kernel filenames, and should trigger warnings +#include "kernel.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: including 'kernel.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "Verilog.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: including 'Verilog.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "vhdl.CL" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: including 'vhdl.CL' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [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: including 'kernel.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "somedir/verilog.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: including 'verilog.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [altera-kernel-name-restriction] +#include "otherdir/vhdl.cl" +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: including 'vhdl.cl' may cause additional compilation errors due to the name of the kernel source file; consider renaming the included kernel source file [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, and are not the kernel source file name. +#include "some_kernel.cl" +#include "other_Verilog.cl" +#include "vhdl_number_two.cl" + +// Naming a directory kernel.cl, verilog.cl, or vhdl.cl is not explicitly +// forbidden in the Altera Programming Guide either. +#include "some/kernel.cl/foo.h" +#include "some/verilog.cl/foo.h" +#include "some/vhdl.cl/foo.h" +#endif + 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", ] }