xref: /llvm-project/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp (revision df0c8f25145047731fb95b4ce7153ce6fb5b6f5d)
1cbbf9282SRoman Lebedev //===--- UseDefaultNoneCheck.cpp - clang-tidy -----------------------------===//
2cbbf9282SRoman Lebedev //
3cbbf9282SRoman Lebedev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cbbf9282SRoman Lebedev // See https://llvm.org/LICENSE.txt for license information.
5cbbf9282SRoman Lebedev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cbbf9282SRoman Lebedev //
7cbbf9282SRoman Lebedev //===----------------------------------------------------------------------===//
8cbbf9282SRoman Lebedev 
9cbbf9282SRoman Lebedev #include "UseDefaultNoneCheck.h"
10cbbf9282SRoman Lebedev #include "clang/AST/ASTContext.h"
11cbbf9282SRoman Lebedev #include "clang/AST/OpenMPClause.h"
12cbbf9282SRoman Lebedev #include "clang/AST/Stmt.h"
13cbbf9282SRoman Lebedev #include "clang/AST/StmtOpenMP.h"
14cbbf9282SRoman Lebedev #include "clang/ASTMatchers/ASTMatchFinder.h"
15cbbf9282SRoman Lebedev #include "clang/ASTMatchers/ASTMatchers.h"
16cbbf9282SRoman Lebedev #include "clang/ASTMatchers/ASTMatchersMacros.h"
17cbbf9282SRoman Lebedev 
18cbbf9282SRoman Lebedev using namespace clang::ast_matchers;
19cbbf9282SRoman Lebedev 
207d2ea6c4SCarlos Galvez namespace clang::tidy::openmp {
21cbbf9282SRoman Lebedev 
registerMatchers(MatchFinder * Finder)22cbbf9282SRoman Lebedev void UseDefaultNoneCheck::registerMatchers(MatchFinder *Finder) {
23cbbf9282SRoman Lebedev   Finder->addMatcher(
24cbbf9282SRoman Lebedev       ompExecutableDirective(
25*df0c8f25SNathan James           isAllowedToContainClauseKind(llvm::omp::OMPC_default),
26cbbf9282SRoman Lebedev           anyOf(unless(hasAnyClause(ompDefaultClause())),
27*df0c8f25SNathan James                 hasAnyClause(
28*df0c8f25SNathan James                     ompDefaultClause(unless(isNoneKind())).bind("clause"))))
29cbbf9282SRoman Lebedev           .bind("directive"),
30cbbf9282SRoman Lebedev       this);
31cbbf9282SRoman Lebedev }
32cbbf9282SRoman Lebedev 
check(const MatchFinder::MatchResult & Result)33cbbf9282SRoman Lebedev void UseDefaultNoneCheck::check(const MatchFinder::MatchResult &Result) {
34cbbf9282SRoman Lebedev   const auto *Directive =
35cbbf9282SRoman Lebedev       Result.Nodes.getNodeAs<OMPExecutableDirective>("directive");
36cbbf9282SRoman Lebedev   assert(Directive != nullptr && "Expected to match some directive.");
37cbbf9282SRoman Lebedev 
38cbbf9282SRoman Lebedev   if (const auto *Clause = Result.Nodes.getNodeAs<OMPDefaultClause>("clause")) {
39cbbf9282SRoman Lebedev     diag(Directive->getBeginLoc(),
40cbbf9282SRoman Lebedev          "OpenMP directive '%0' specifies 'default(%1)' clause, consider using "
41cbbf9282SRoman Lebedev          "'default(none)' clause instead")
42cbbf9282SRoman Lebedev         << getOpenMPDirectiveName(Directive->getDirectiveKind())
43cbbf9282SRoman Lebedev         << getOpenMPSimpleClauseTypeName(Clause->getClauseKind(),
44803ad313SJohannes Doerfert                                          unsigned(Clause->getDefaultKind()));
45cbbf9282SRoman Lebedev     diag(Clause->getBeginLoc(), "existing 'default' clause specified here",
46cbbf9282SRoman Lebedev          DiagnosticIDs::Note);
47cbbf9282SRoman Lebedev     return;
48cbbf9282SRoman Lebedev   }
49cbbf9282SRoman Lebedev 
50cbbf9282SRoman Lebedev   diag(Directive->getBeginLoc(),
51cbbf9282SRoman Lebedev        "OpenMP directive '%0' does not specify 'default' clause, consider "
52cbbf9282SRoman Lebedev        "specifying 'default(none)' clause")
53cbbf9282SRoman Lebedev       << getOpenMPDirectiveName(Directive->getDirectiveKind());
54cbbf9282SRoman Lebedev }
55cbbf9282SRoman Lebedev 
567d2ea6c4SCarlos Galvez } // namespace clang::tidy::openmp
57