Add a new altera kernel name restriction check to clang-tidy.
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."
This reverts the reversion from 43a38a65233039b5e71797a644d41a890f8d7f2b.
diff --git a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
index d91f67a..d3e906b 100644
--- a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
+++ b/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<KernelNameRestrictionCheck>(
+ "altera-kernel-name-restriction");
CheckFactories.registerCheck<StructPackAlignCheck>(
"altera-struct-pack-align");
}
diff --git a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt
index ed28d9f..8ab5cc1 100644
--- a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt
@@ -5,6 +5,7 @@
add_clang_library(clangTidyAlteraModule
AlteraTidyModule.cpp
+ KernelNameRestrictionCheck.cpp
StructPackAlignCheck.cpp
LINK_LIBS
diff --git a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp
new file mode 100644
index 0000000..eb49977
--- /dev/null
+++ b/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 <string>
+#include <vector>
+
+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<IncludeDirective> IncludeDirectives;
+ ClangTidyCheck &Check;
+ const SourceManager &SM;
+};
+
+} // namespace
+
+void KernelNameRestrictionCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *) {
+ PP->addPPCallbacks(
+ std::make_unique<KernelNameRestrictionPPCallbacks>(*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
diff --git a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.h b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.h
new file mode 100644
index 0000000..cf91ca1
--- /dev/null
+++ b/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