aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/check-omp-structure.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics/check-omp-structure.cpp')
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp85
1 files changed, 70 insertions, 15 deletions
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index e9bd34d..57bc53c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -624,21 +624,11 @@ template <typename Checker> struct DirectiveSpellingVisitor {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_assumes);
return false;
}
- bool Pre(const parser::OpenMPDeclareSimdConstruct &x) {
- checker_(
- std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_simd);
- return false;
- }
bool Pre(const parser::OpenMPDeclareTargetConstruct &x) {
checker_(
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_target);
return false;
}
- bool Pre(const parser::OmpDeclareVariantDirective &x) {
- checker_(std::get<parser::Verbatim>(x.t).source,
- Directive::OMPD_declare_variant);
- return false;
- }
bool Pre(const parser::OpenMPGroupprivate &x) {
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
return false;
@@ -1361,8 +1351,32 @@ void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &x) {
}
void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
- const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_declare_simd);
+ const parser::OmpDirectiveName &dirName{x.v.DirName()};
+ PushContextAndClauseSets(dirName.source, dirName.v);
+
+ const parser::OmpArgumentList &args{x.v.Arguments()};
+ if (args.v.empty()) {
+ return;
+ } else if (args.v.size() > 1) {
+ context_.Say(args.source,
+ "DECLARE_SIMD directive should have at most one argument"_err_en_US);
+ return;
+ }
+
+ const parser::OmpArgument &arg{args.v.front()};
+ if (auto *sym{GetArgumentSymbol(arg)}) {
+ if (!IsProcedure(*sym) && !IsFunction(*sym)) {
+ auto &msg{context_.Say(arg.source,
+ "The name '%s' should refer to a procedure"_err_en_US, sym->name())};
+ if (sym->test(Symbol::Flag::Implicit)) {
+ msg.Attach(arg.source,
+ "The name '%s' has been implicitly declared"_en_US, sym->name());
+ }
+ }
+ } else {
+ context_.Say(arg.source,
+ "The argument to the DECLARE_SIMD directive should be a procedure name"_err_en_US);
+ }
}
void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
@@ -1370,9 +1384,50 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
}
void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) {
- const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContextAndClauseSets(
- dir.source, llvm::omp::Directive::OMPD_declare_variant);
+ const parser::OmpDirectiveName &dirName{x.v.DirName()};
+ PushContextAndClauseSets(dirName.source, dirName.v);
+
+ const parser::OmpArgumentList &args{x.v.Arguments()};
+ if (args.v.size() != 1) {
+ context_.Say(args.source,
+ "DECLARE_VARIANT directive should have a single argument"_err_en_US);
+ return;
+ }
+
+ auto InvalidArgument{[&](parser::CharBlock source) {
+ context_.Say(source,
+ "The argument to the DECLARE_VARIANT directive should be [base-name:]variant-name"_err_en_US);
+ }};
+
+ auto CheckSymbol{[&](const Symbol *sym, parser::CharBlock source) {
+ if (sym) {
+ if (!IsProcedure(*sym) && !IsFunction(*sym)) {
+ auto &msg{context_.Say(source,
+ "The name '%s' should refer to a procedure"_err_en_US,
+ sym->name())};
+ if (sym->test(Symbol::Flag::Implicit)) {
+ msg.Attach(source, "The name '%s' has been implicitly declared"_en_US,
+ sym->name());
+ }
+ }
+ } else {
+ InvalidArgument(source);
+ }
+ }};
+
+ const parser::OmpArgument &arg{args.v.front()};
+ common::visit( //
+ common::visitors{
+ [&](const parser::OmpBaseVariantNames &y) {
+ CheckSymbol(GetObjectSymbol(std::get<0>(y.t)), arg.source);
+ CheckSymbol(GetObjectSymbol(std::get<1>(y.t)), arg.source);
+ },
+ [&](const parser::OmpLocator &y) {
+ CheckSymbol(GetArgumentSymbol(arg), arg.source);
+ },
+ [&](auto &&y) { InvalidArgument(arg.source); },
+ },
+ arg.u);
}
void OmpStructureChecker::Leave(const parser::OmpDeclareVariantDirective &) {