[flang] Allow compiler directives in more places

Allow compiler directives in the implicit-part and before USE statements
in the specification-part.

Differential Revision: https://reviews.llvm.org/D85693
This commit is contained in:
Tim Keith 2020-08-11 08:37:23 -07:00
parent aa994d9867
commit cf715717aa
5 changed files with 20 additions and 5 deletions

View File

@ -403,7 +403,8 @@ struct ImplicitPartStmt {
Statement<common::Indirection<ParameterStmt>>,
Statement<common::Indirection<OldParameterStmt>>,
Statement<common::Indirection<FormatStmt>>,
Statement<common::Indirection<EntryStmt>>>
Statement<common::Indirection<EntryStmt>>,
common::Indirection<CompilerDirective>>
u;
};
@ -430,6 +431,7 @@ struct SpecificationPart {
TUPLE_CLASS_BOILERPLATE(SpecificationPart);
std::tuple<std::list<OpenACCDeclarativeConstruct>,
std::list<OpenMPDeclarativeConstruct>,
std::list<common::Indirection<CompilerDirective>>,
std::list<Statement<common::Indirection<UseStmt>>>,
std::list<Statement<common::Indirection<ImportStmt>>>, ImplicitPart,
std::list<DeclarationConstruct>>

View File

@ -116,7 +116,8 @@ TYPE_PARSER(first(
construct<ImplicitPartStmt>(statement(indirect(parameterStmt))),
construct<ImplicitPartStmt>(statement(indirect(oldParameterStmt))),
construct<ImplicitPartStmt>(statement(indirect(formatStmt))),
construct<ImplicitPartStmt>(statement(indirect(entryStmt)))))
construct<ImplicitPartStmt>(statement(indirect(entryStmt))),
construct<ImplicitPartStmt>(indirect(compilerDirective))))
// R512 internal-subprogram -> function-subprogram | subroutine-subprogram
// Internal subprograms are not program units, so their END statements

View File

@ -61,7 +61,7 @@ TYPE_PARSER(construct<ProgramUnit>(indirect(Parser<Module>{})) ||
// [declaration-construct]...
TYPE_CONTEXT_PARSER("specification part"_en_US,
construct<SpecificationPart>(many(openaccDeclarativeConstruct),
many(openmpDeclarativeConstruct),
many(openmpDeclarativeConstruct), many(indirect(compilerDirective)),
many(statement(indirect(Parser<UseStmt>{}))),
many(unambiguousStatement(indirect(Parser<ImportStmt>{}))),
implicitPart, many(declarationConstruct)))
@ -128,7 +128,7 @@ constexpr auto limitedDeclarationConstruct{recovery(
// statement.
constexpr auto limitedSpecificationPart{inContext("specification part"_en_US,
construct<SpecificationPart>(many(openaccDeclarativeConstruct),
many(openmpDeclarativeConstruct),
many(openmpDeclarativeConstruct), many(indirect(compilerDirective)),
many(statement(indirect(Parser<UseStmt>{}))),
many(unambiguousStatement(indirect(Parser<ImportStmt>{}))),
implicitPart, many(limitedDeclarationConstruct)))};

View File

@ -5916,7 +5916,8 @@ bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
Walk(std::get<2>(x.t));
Walk(std::get<3>(x.t));
Walk(std::get<4>(x.t));
const std::list<parser::DeclarationConstruct> &decls{std::get<5>(x.t)};
Walk(std::get<5>(x.t));
const std::list<parser::DeclarationConstruct> &decls{std::get<6>(x.t)};
for (const auto &decl : decls) {
if (const auto *spec{
std::get_if<parser::SpecificationConstruct>(&decl.u)}) {

View File

@ -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