diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 11725991e9c9a..a8947fddaf216 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -208,6 +208,8 @@ class ParseTreeDumper { NODE(CompilerDirective, NameValue) NODE(CompilerDirective, Unrecognized) NODE(CompilerDirective, VectorAlways) + NODE(CompilerDirective, Error) + NODE(CompilerDirective, Warning) NODE(parser, ComplexLiteralConstant) NODE(parser, ComplexPart) NODE(parser, ComponentArraySpec) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 00d85aa05fb3a..700cad310960e 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3363,6 +3363,12 @@ struct CompilerDirective { TUPLE_CLASS_BOILERPLATE(AssumeAligned); std::tuple, uint64_t> t; }; + struct Error { + WRAPPER_CLASS_BOILERPLATE(Error, std::string); + }; + struct Warning { + WRAPPER_CLASS_BOILERPLATE(Warning, std::string); + }; EMPTY_CLASS(VectorAlways); struct NameValue { TUPLE_CLASS_BOILERPLATE(NameValue); @@ -3370,8 +3376,8 @@ struct CompilerDirective { }; EMPTY_CLASS(Unrecognized); CharBlock source; - std::variant, LoopCount, std::list, - VectorAlways, std::list, Unrecognized> + std::variant, LoopCount, std::list, Error, + Warning, VectorAlways, std::list, Unrecognized> u; }; diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index 7cb35c1f173bb..2b9f8ef6ca695 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1294,6 +1294,8 @@ TYPE_PARSER(construct("STAT =" >> statVariable) || // !DIR$ LOOP COUNT (n1[, n2]...) // !DIR$ name[=value] [, name[=value]]... // !DIR$ +// !DIR$ ERROR error-string +// !DIR$ WARNING warning-string constexpr auto ignore_tkr{ "IGNORE_TKR" >> optionalList(construct( maybe(parenthesized(many(letter))), name))}; @@ -1305,11 +1307,17 @@ constexpr auto assumeAligned{"ASSUME_ALIGNED" >> indirect(designator), ":"_tok >> digitString64))}; constexpr auto vectorAlways{ "VECTOR ALWAYS" >> construct()}; +constexpr auto error{"ERROR" >> + construct(charLiteralConstantWithoutKind)}; +constexpr auto warning{"WARNING" >> + construct(charLiteralConstantWithoutKind)}; TYPE_PARSER(beginDirective >> "DIR$ "_tok >> sourced((construct(ignore_tkr) || construct(loopCount) || construct(assumeAligned) || construct(vectorAlways) || + construct(error) || + construct(warning) || construct( many(construct( name, maybe(("="_tok || ":"_tok) >> digitString64))))) / diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 7bf404bba2c3e..5c92a59d334db 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1847,6 +1847,8 @@ class UnparseVisitor { [&](const std::list &names) { Walk("!DIR$ ", names, " "); }, + [&](const CompilerDirective::Error &) { Word("!DIR$ ERROR"); }, + [&](const CompilerDirective::Warning &) { Word("!DIR$ WARNING"); }, [&](const CompilerDirective::Unrecognized &) { Word("!DIR$ "); Word(x.source.ToString()); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index f3c2a5bf094d0..1e00eb29aabd3 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -9248,7 +9248,12 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) { if (std::holds_alternative(x.u)) { return; } - if (const auto *tkr{ + if (const auto *err{std::get_if(&x.u)}) { + Say(err->v, "%s"_err_en_US); + } + else if (const auto *warn{std::get_if(&x.u)}) { + Say(warn->v, "%s"_warn_en_US); + } else if (const auto *tkr{ std::get_if>(&x.u)}) { if (currScope().IsTopLevel() || GetProgramUnitContaining(currScope()).kind() != diff --git a/flang/test/Parser/compiler-directive-error.f90 b/flang/test/Parser/compiler-directive-error.f90 new file mode 100644 index 0000000000000..d9f253ab3a41a --- /dev/null +++ b/flang/test/Parser/compiler-directive-error.f90 @@ -0,0 +1,8 @@ +! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s + +! Test that error compiler directive issues error +program error +!dir$ error "Error!" +!CHECK: error: Error! +end program + diff --git a/flang/test/Parser/compiler-directive-warning.f90 b/flang/test/Parser/compiler-directive-warning.f90 new file mode 100644 index 0000000000000..3fa5ede7105fc --- /dev/null +++ b/flang/test/Parser/compiler-directive-warning.f90 @@ -0,0 +1,8 @@ +! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s + +! Test that warning compiler directive issues warning +program warn +!dir$ warning "Warning!" +!CHECK: warning: Warning! +end program +