103 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "KernelNameRestrictionCheck.h"10#include "clang/Frontend/CompilerInstance.h"11#include "clang/Lex/PPCallbacks.h"12#include "clang/Lex/Preprocessor.h"13#include <vector>14 15using namespace clang::ast_matchers;16 17namespace clang::tidy::altera {18 19namespace {20 21class KernelNameRestrictionPPCallbacks : public PPCallbacks {22public:23 explicit KernelNameRestrictionPPCallbacks(ClangTidyCheck &Check,24 const SourceManager &SM)25 : Check(Check), SM(SM) {}26 27 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,28 StringRef FileName, bool IsAngled,29 CharSourceRange FileNameRange,30 OptionalFileEntryRef File, StringRef SearchPath,31 StringRef RelativePath, const Module *SuggestedModule,32 bool ModuleImported,33 SrcMgr::CharacteristicKind FileType) override;34 35 void EndOfMainFile() override;36 37private:38 /// Returns true if the name of the file with path FileName is 'kernel.cl',39 /// 'verilog.cl', or 'vhdl.cl'. The file name check is case insensitive.40 bool fileNameIsRestricted(StringRef FileName);41 42 struct IncludeDirective {43 SourceLocation Loc; // Location in the include directive.44 StringRef FileName; // Filename as a string.45 };46 47 std::vector<IncludeDirective> IncludeDirectives;48 ClangTidyCheck &Check;49 const SourceManager &SM;50};51 52} // namespace53 54void KernelNameRestrictionCheck::registerPPCallbacks(const SourceManager &SM,55 Preprocessor *PP,56 Preprocessor *) {57 PP->addPPCallbacks(58 std::make_unique<KernelNameRestrictionPPCallbacks>(*this, SM));59}60 61void KernelNameRestrictionPPCallbacks::InclusionDirective(62 SourceLocation HashLoc, const Token &, StringRef FileName, bool,63 CharSourceRange, OptionalFileEntryRef, StringRef, StringRef, const Module *,64 bool, SrcMgr::CharacteristicKind) {65 IncludeDirective ID = {HashLoc, FileName};66 IncludeDirectives.push_back(std::move(ID));67}68 69bool KernelNameRestrictionPPCallbacks::fileNameIsRestricted(70 StringRef FileName) {71 return FileName.equals_insensitive("kernel.cl") ||72 FileName.equals_insensitive("verilog.cl") ||73 FileName.equals_insensitive("vhdl.cl");74}75 76void KernelNameRestrictionPPCallbacks::EndOfMainFile() {77 // Check main file for restricted names.78 OptionalFileEntryRef Entry = SM.getFileEntryRefForID(SM.getMainFileID());79 const StringRef FileName = llvm::sys::path::filename(Entry->getName());80 if (fileNameIsRestricted(FileName))81 Check.diag(SM.getLocForStartOfFile(SM.getMainFileID()),82 "compiling '%0' may cause additional compilation errors due "83 "to the name of the kernel source file; consider renaming the "84 "included kernel source file")85 << FileName;86 87 if (IncludeDirectives.empty())88 return;89 90 // Check included files for restricted names.91 for (const IncludeDirective &ID : IncludeDirectives) {92 const StringRef FileName = llvm::sys::path::filename(ID.FileName);93 if (fileNameIsRestricted(FileName))94 Check.diag(ID.Loc,95 "including '%0' may cause additional compilation errors due "96 "to the name of the kernel source file; consider renaming the "97 "included kernel source file")98 << FileName;99 }100}101 102} // namespace clang::tidy::altera103