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