diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index b2c3d92909375..06c168a5de612 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -207,6 +207,7 @@ class ParseTreeDumper { NODE(CompilerDirective, LoopCount) NODE(CompilerDirective, AssumeAligned) NODE(CompilerDirective, NameValue) + NODE(CompilerDirective, Unrecognized) NODE(parser, ComplexLiteralConstant) NODE(parser, ComplexPart) NODE(parser, ComponentArraySpec) diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h index 79ea29f4b7f32..81d01dbdd65cc 100644 --- a/flang/include/flang/Parser/parse-tree-visitor.h +++ b/flang/include/flang/Parser/parse-tree-visitor.h @@ -861,6 +861,18 @@ template void Walk(CompilerDirective &x, M &mutator) { } } template +void Walk(const CompilerDirective::Unrecognized &x, V &visitor) { + if (visitor.Pre(x)) { + visitor.Post(x); + } +} +template +void Walk(CompilerDirective::Unrecognized &x, M &mutator) { + if (mutator.Pre(x)) { + mutator.Post(x); + } +} +template void Walk(const OmpLinearClause::WithModifier &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.modifier, visitor); diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index c96abfba491d4..85e8121dd1250 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3298,7 +3298,8 @@ struct StmtFunctionStmt { // Compiler directives // !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]... // !DIR$ LOOP COUNT (n1[, n2]...) -// !DIR$ name... +// !DIR$ name[=value] [, name[=value]]... = can be : +// !DIR$ struct CompilerDirective { UNION_CLASS_BOILERPLATE(CompilerDirective); struct IgnoreTKR { @@ -3316,9 +3317,10 @@ struct CompilerDirective { TUPLE_CLASS_BOILERPLATE(NameValue); std::tuple> t; }; + struct Unrecognized {}; CharBlock source; std::variant, LoopCount, std::list, - std::list> + std::list, Unrecognized> u; }; diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index fc81a477897a3..fd28eea0f947d 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1261,24 +1261,28 @@ TYPE_PARSER(construct("STAT =" >> statVariable) || // Directives, extensions, and deprecated statements // !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]... // !DIR$ LOOP COUNT (n1[, n2]...) -// !DIR$ name... +// !DIR$ name[=value] [, name[=value]]... +// !DIR$ constexpr auto ignore_tkr{ - "DIR$ IGNORE_TKR" >> optionalList(construct( - maybe(parenthesized(many(letter))), name))}; + "IGNORE_TKR" >> optionalList(construct( + maybe(parenthesized(many(letter))), name))}; constexpr auto loopCount{ - "DIR$ LOOP COUNT" >> construct( - parenthesized(nonemptyList(digitString64)))}; -constexpr auto assumeAligned{"DIR$ ASSUME_ALIGNED" >> + "LOOP COUNT" >> construct( + parenthesized(nonemptyList(digitString64)))}; +constexpr auto assumeAligned{"ASSUME_ALIGNED" >> optionalList(construct( indirect(designator), ":"_tok >> digitString64))}; -TYPE_PARSER(beginDirective >> - sourced(construct(ignore_tkr) || - construct(loopCount) || - construct(assumeAligned) || +TYPE_PARSER(beginDirective >> "DIR$ "_tok >> + sourced((construct(ignore_tkr) || + construct(loopCount) || + construct(assumeAligned) || + construct( + many(construct( + name, maybe(("="_tok || ":"_tok) >> digitString64))))) / + endOfStmt || construct( - "DIR$" >> many(construct(name, - maybe(("="_tok || ":"_tok) >> digitString64))))) / - endOfStmt) + SkipTo<'\n'>{} >> pure()) / + endOfStmt)) TYPE_PARSER(extension( "nonstandard usage: based POINTER"_port_en_US, diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index baba4863f5775..c06458833f072 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1827,6 +1827,10 @@ class UnparseVisitor { [&](const std::list &names) { Walk("!DIR$ ", names, " "); }, + [&](const CompilerDirective::Unrecognized &) { + Word("!DIR$ "); + Word(x.source.ToString()); + }, }, x.u); Put('\n'); diff --git a/flang/test/Parser/unrecognized-dir.f90 b/flang/test/Parser/unrecognized-dir.f90 new file mode 100644 index 0000000000000..ba6fff7562e2d --- /dev/null +++ b/flang/test/Parser/unrecognized-dir.f90 @@ -0,0 +1,4 @@ +! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s +!CHECK: warning: Compiler directive was ignored +!DIR$ Not a recognized directive +end