diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -403,7 +403,8 @@ Statement>, Statement>, Statement>, - Statement>> + Statement>, + common::Indirection> u; }; @@ -430,6 +431,7 @@ TUPLE_CLASS_BOILERPLATE(SpecificationPart); std::tuple, std::list, + std::list>, std::list>>, std::list>>, ImplicitPart, std::list> diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -116,7 +116,8 @@ construct(statement(indirect(parameterStmt))), construct(statement(indirect(oldParameterStmt))), construct(statement(indirect(formatStmt))), - construct(statement(indirect(entryStmt))))) + construct(statement(indirect(entryStmt))), + construct(indirect(compilerDirective)))) // R512 internal-subprogram -> function-subprogram | subroutine-subprogram // Internal subprograms are not program units, so their END statements diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp --- a/flang/lib/Parser/program-parsers.cpp +++ b/flang/lib/Parser/program-parsers.cpp @@ -61,7 +61,7 @@ // [declaration-construct]... TYPE_CONTEXT_PARSER("specification part"_en_US, construct(many(openaccDeclarativeConstruct), - many(openmpDeclarativeConstruct), + many(openmpDeclarativeConstruct), many(indirect(compilerDirective)), many(statement(indirect(Parser{}))), many(unambiguousStatement(indirect(Parser{}))), implicitPart, many(declarationConstruct))) @@ -128,7 +128,7 @@ // statement. constexpr auto limitedSpecificationPart{inContext("specification part"_en_US, construct(many(openaccDeclarativeConstruct), - many(openmpDeclarativeConstruct), + many(openmpDeclarativeConstruct), many(indirect(compilerDirective)), many(statement(indirect(Parser{}))), many(unambiguousStatement(indirect(Parser{}))), implicitPart, many(limitedDeclarationConstruct)))}; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -5916,7 +5916,8 @@ Walk(std::get<2>(x.t)); Walk(std::get<3>(x.t)); Walk(std::get<4>(x.t)); - const std::list &decls{std::get<5>(x.t)}; + Walk(std::get<5>(x.t)); + const std::list &decls{std::get<6>(x.t)}; for (const auto &decl : decls) { if (const auto *spec{ std::get_if(&decl.u)}) { diff --git a/flang/test/Parser/compiler-directives.f90 b/flang/test/Parser/compiler-directives.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/compiler-directives.f90 @@ -0,0 +1,11 @@ +! RUN: %f18 -funparse %s 2>&1 + +! Test that compiler directives can appear in various places. + +module m + !dir$ integer + use iso_fortran_env + !dir$ integer + implicit integer(a-z) + !dir$ integer +end