Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ class SemanticsContext {
const Scope &FindScope(parser::CharBlock) const;
Scope &FindScope(parser::CharBlock);
void UpdateScopeIndex(Scope &, parser::CharBlock);
void DumpScopeIndex(llvm::raw_ostream &) const;

bool IsInModuleFile(parser::CharBlock) const;

Expand Down
71 changes: 35 additions & 36 deletions flang/lib/Parser/openacc-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,21 @@ TYPE_PARSER(
// tile size is one of:
// * (represented as an empty std::optional<ScalarIntExpr>)
// constant-int-expr
TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) ||
TYPE_PARSER(sourced(construct<AccTileExpr>(scalarIntConstantExpr) ||
construct<AccTileExpr>(
"*" >> construct<std::optional<ScalarIntConstantExpr>>()))
"*" >> construct<std::optional<ScalarIntConstantExpr>>())))
TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{})))

// 2.9 (1979-1982) gang-arg is one of :
// [num:]int-expr
// dim:int-expr
// static:size-expr
TYPE_PARSER(construct<AccGangArg>(construct<AccGangArg::Static>(
"STATIC: " >> Parser<AccSizeExpr>{})) ||
TYPE_PARSER(sourced(construct<AccGangArg>(construct<AccGangArg::Static>(
"STATIC: " >> Parser<AccSizeExpr>{})) ||
construct<AccGangArg>(
construct<AccGangArg::Dim>("DIM: " >> scalarIntExpr)) ||
construct<AccGangArg>(
construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr)))
construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr))))

// 2.9 gang-arg-list
TYPE_PARSER(
Expand All @@ -101,7 +101,7 @@ TYPE_PARSER(construct<AccCollapseArg>(

// 2.5.15 Reduction, F'2023 R1131, and CUF reduction-op
// Operator for reduction
TYPE_PARSER(sourced(construct<ReductionOperator>(
TYPE_PARSER(construct<ReductionOperator>(
first("+" >> pure(ReductionOperator::Operator::Plus),
"*" >> pure(ReductionOperator::Operator::Multiply),
"MAX" >> pure(ReductionOperator::Operator::Max),
Expand All @@ -112,32 +112,32 @@ TYPE_PARSER(sourced(construct<ReductionOperator>(
".AND." >> pure(ReductionOperator::Operator::And),
".OR." >> pure(ReductionOperator::Operator::Or),
".EQV." >> pure(ReductionOperator::Operator::Eqv),
".NEQV." >> pure(ReductionOperator::Operator::Neqv)))))
".NEQV." >> pure(ReductionOperator::Operator::Neqv))))

// 2.15.1 Bind clause
TYPE_PARSER(sourced(construct<AccBindClause>(name)) ||
sourced(construct<AccBindClause>(scalarDefaultCharExpr)))
TYPE_PARSER(sourced(construct<AccBindClause>(name) ||
construct<AccBindClause>(scalarDefaultCharExpr)))

// 2.5.16 Default clause
TYPE_PARSER(construct<AccDefaultClause>(
TYPE_PARSER(sourced(construct<AccDefaultClause>(
first("NONE" >> pure(llvm::acc::DefaultValue::ACC_Default_none),
"PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present))))
"PRESENT" >> pure(llvm::acc::DefaultValue::ACC_Default_present)))))

// SELF clause is either a simple optional condition for compute construct
// or a synonym of the HOST clause for the update directive 2.14.4 holding
// an object list.
TYPE_PARSER(
TYPE_PARSER(sourced(
construct<AccSelfClause>(Parser<AccObjectList>{}) / lookAhead(")"_tok) ||
construct<AccSelfClause>(scalarLogicalExpr / lookAhead(")"_tok)) ||
construct<AccSelfClause>(scalarLogicalExpr) / lookAhead(")"_tok) ||
construct<AccSelfClause>(
recovery(fail<std::optional<ScalarLogicalExpr>>(
"logical expression or object list expected"_err_en_US),
SkipTo<')'>{} >> pure<std::optional<ScalarLogicalExpr>>())))
SkipTo<')'>{} >> pure<std::optional<ScalarLogicalExpr>>()))))

// Modifier for copyin, copyout, cache and create
TYPE_PARSER(construct<AccDataModifier>(
TYPE_PARSER(sourced(construct<AccDataModifier>(
first("ZERO:" >> pure(AccDataModifier::Modifier::Zero),
"READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly))))
"READONLY:" >> pure(AccDataModifier::Modifier::ReadOnly)))))

// Combined directives
TYPE_PARSER(sourced(construct<AccCombinedDirective>(
Expand Down Expand Up @@ -166,14 +166,13 @@ TYPE_PARSER(sourced(construct<AccStandaloneDirective>(
TYPE_PARSER(sourced(construct<AccLoopDirective>(
first("LOOP" >> pure(llvm::acc::Directive::ACCD_loop)))))

TYPE_PARSER(construct<AccBeginLoopDirective>(
sourced(Parser<AccLoopDirective>{}), Parser<AccClauseList>{}))
TYPE_PARSER(sourced(construct<AccBeginLoopDirective>(
Parser<AccLoopDirective>{}, Parser<AccClauseList>{})))

TYPE_PARSER(construct<AccEndLoop>("END LOOP"_tok))

TYPE_PARSER(construct<OpenACCLoopConstruct>(
sourced(Parser<AccBeginLoopDirective>{} / endAccLine),
maybe(Parser<DoConstruct>{}),
Parser<AccBeginLoopDirective>{} / endAccLine, maybe(Parser<DoConstruct>{}),
maybe(startAccLine >> Parser<AccEndLoop>{} / endAccLine)))

// 2.15.1 Routine directive
Expand All @@ -186,8 +185,8 @@ TYPE_PARSER(sourced(
parenthesized(Parser<AccObjectListWithModifier>{}))))

// 2.11 Combined constructs
TYPE_PARSER(construct<AccBeginCombinedDirective>(
sourced(Parser<AccCombinedDirective>{}), Parser<AccClauseList>{}))
TYPE_PARSER(sourced(construct<AccBeginCombinedDirective>(
Parser<AccCombinedDirective>{}, Parser<AccClauseList>{})))

// 2.12 Atomic constructs
TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok))
Expand All @@ -213,10 +212,10 @@ TYPE_PARSER("ATOMIC" >>
statement(assignmentStmt), Parser<AccEndAtomic>{} / endAccLine))

TYPE_PARSER(
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) ||
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{})) ||
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{})) ||
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{})))
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{}) ||
construct<OpenACCAtomicConstruct>(Parser<AccAtomicCapture>{}) ||
construct<OpenACCAtomicConstruct>(Parser<AccAtomicWrite>{}) ||
construct<OpenACCAtomicConstruct>(Parser<AccAtomicUpdate>{})))

// 2.13 Declare constructs
TYPE_PARSER(sourced(construct<AccDeclarativeDirective>(
Expand Down Expand Up @@ -250,18 +249,18 @@ TYPE_PARSER(construct<OpenACCBlockConstruct>(
pure(llvm::acc::Directive::ACCD_data))))))

// Standalone constructs
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(
sourced(Parser<AccStandaloneDirective>{}), Parser<AccClauseList>{}))
TYPE_PARSER(sourced(construct<OpenACCStandaloneConstruct>(
Parser<AccStandaloneDirective>{}, Parser<AccClauseList>{})))

// Standalone declarative constructs
TYPE_PARSER(construct<OpenACCStandaloneDeclarativeConstruct>(
sourced(Parser<AccDeclarativeDirective>{}), Parser<AccClauseList>{}))
TYPE_PARSER(sourced(construct<OpenACCStandaloneDeclarativeConstruct>(
Parser<AccDeclarativeDirective>{}, Parser<AccClauseList>{})))

TYPE_PARSER(startAccLine >>
withMessage("expected OpenACC directive"_err_en_US,
first(sourced(construct<OpenACCDeclarativeConstruct>(
Parser<OpenACCStandaloneDeclarativeConstruct>{})),
sourced(construct<OpenACCDeclarativeConstruct>(
sourced(first(construct<OpenACCDeclarativeConstruct>(
Parser<OpenACCStandaloneDeclarativeConstruct>{}),
construct<OpenACCDeclarativeConstruct>(
Parser<OpenACCRoutineConstruct>{})))))

TYPE_PARSER(sourced(construct<OpenACCEndConstruct>(
Expand Down Expand Up @@ -293,9 +292,9 @@ TYPE_PARSER(startAccLine >>
"SERIAL"_tok >> maybe("LOOP"_tok) >>
pure(llvm::acc::Directive::ACCD_serial_loop))))))

TYPE_PARSER(construct<OpenACCCombinedConstruct>(
sourced(Parser<AccBeginCombinedDirective>{} / endAccLine),
TYPE_PARSER(sourced(construct<OpenACCCombinedConstruct>(
Parser<AccBeginCombinedDirective>{} / endAccLine,
maybe(Parser<DoConstruct>{}),
maybe(Parser<AccEndCombinedDirective>{} / endAccLine)))
maybe(Parser<AccEndCombinedDirective>{} / endAccLine))))

} // namespace Fortran::parser
82 changes: 37 additions & 45 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
#include <list>
#include <map>

namespace Fortran::semantics {

template <typename T>
static Fortran::semantics::Scope *GetScope(
Fortran::semantics::SemanticsContext &context, const T &x) {
std::optional<Fortran::parser::CharBlock> source{GetLastSource(x)};
return source ? &context.FindScope(*source) : nullptr;
static Scope *GetScope(SemanticsContext &context, const T &x) {
if (auto source{GetLastSource(x)}) {
return &context.FindScope(*source);
} else {
return nullptr;
}
}

namespace Fortran::semantics {

template <typename T> class DirectiveAttributeVisitor {
public:
explicit DirectiveAttributeVisitor(SemanticsContext &context)
Expand Down Expand Up @@ -361,7 +363,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
void ResolveAccObject(const parser::AccObject &, Symbol::Flag);
Symbol *ResolveAcc(const parser::Name &, Symbol::Flag, Scope &);
Symbol *ResolveAcc(Symbol &, Symbol::Flag, Scope &);
Symbol *ResolveName(const parser::Name &, bool parentScope = false);
Symbol *ResolveName(const parser::Name &);
Symbol *ResolveFctName(const parser::Name &);
Symbol *ResolveAccCommonBlockName(const parser::Name *);
Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
Expand Down Expand Up @@ -1257,31 +1259,22 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCStandaloneConstruct &x) {
return true;
}

Symbol *AccAttributeVisitor::ResolveName(
const parser::Name &name, bool parentScope) {
Symbol *prev{currScope().FindSymbol(name.source)};
// Check in parent scope if asked for.
if (!prev && parentScope) {
prev = currScope().parent().FindSymbol(name.source);
}
if (prev != name.symbol) {
name.symbol = prev;
}
return prev;
Symbol *AccAttributeVisitor::ResolveName(const parser::Name &name) {
return name.symbol;
}

Symbol *AccAttributeVisitor::ResolveFctName(const parser::Name &name) {
Symbol *prev{currScope().FindSymbol(name.source)};
if (!prev || (prev && prev->IsFuncResult())) {
if (prev && prev->IsFuncResult()) {
prev = currScope().parent().FindSymbol(name.source);
if (!prev) {
prev = &context_.globalScope().MakeSymbol(
name.source, Attrs{}, ProcEntityDetails{});
}
}
if (prev != name.symbol) {
name.symbol = prev;
if (!prev) {
prev = &*context_.globalScope()
.try_emplace(name.source, ProcEntityDetails{})
.first->second;
}
CHECK(!name.symbol || name.symbol == prev);
name.symbol = prev;
return prev;
}

Expand Down Expand Up @@ -1388,9 +1381,8 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCRoutineConstruct &x) {
} else {
PushContext(verbatim.source, llvm::acc::Directive::ACCD_routine);
}
const auto &optName{std::get<std::optional<parser::Name>>(x.t)};
if (optName) {
if (Symbol *sym = ResolveFctName(*optName)) {
if (const auto &optName{std::get<std::optional<parser::Name>>(x.t)}) {
if (Symbol * sym{ResolveFctName(*optName)}) {
Symbol &ultimate{sym->GetUltimate()};
AddRoutineInfoToSymbol(ultimate, x);
} else {
Expand Down Expand Up @@ -1425,7 +1417,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
case llvm::acc::Directive::ACCD_kernels_loop:
case llvm::acc::Directive::ACCD_parallel_loop:
case llvm::acc::Directive::ACCD_serial_loop:
PushContext(combinedDir.source, combinedDir.v);
PushContext(x.source, combinedDir.v);
break;
default:
break;
Expand Down Expand Up @@ -1706,26 +1698,27 @@ void AccAttributeVisitor::Post(const parser::AccDefaultClause &x) {
}
}

// For OpenACC constructs, check all the data-refs within the constructs
// and adjust the symbol for each Name if necessary
void AccAttributeVisitor::Post(const parser::Name &name) {
auto *symbol{name.symbol};
if (symbol && WithinConstruct()) {
symbol = &symbol->GetUltimate();
if (!symbol->owner().IsDerivedType() && !symbol->has<ProcEntityDetails>() &&
!symbol->has<SubprogramDetails>() && !IsObjectWithVisibleDSA(*symbol)) {
if (name.symbol && WithinConstruct()) {
const Symbol &symbol{name.symbol->GetUltimate()};
if (!symbol.owner().IsDerivedType() && !symbol.has<ProcEntityDetails>() &&
!symbol.has<SubprogramDetails>() && !IsObjectWithVisibleDSA(symbol)) {
if (Symbol * found{currScope().FindSymbol(name.source)}) {
if (symbol != found) {
name.symbol = found; // adjust the symbol within region
if (&symbol != found) {
// adjust the symbol within the region
// TODO: why didn't name resolution set the right name originally?
name.symbol = found;
} else if (GetContext().defaultDSA == Symbol::Flag::AccNone) {
// 2.5.14.
context_.Say(name.source,
"The DEFAULT(NONE) clause requires that '%s' must be listed in a data-mapping clause"_err_en_US,
symbol->name());
symbol.name());
}
} else {
// TODO: assertion here? or clear name.symbol?
}
}
} // within OpenACC construct
}
}

Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
Expand Down Expand Up @@ -1810,13 +1803,11 @@ Symbol *AccAttributeVisitor::ResolveAcc(

Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
const parser::Name &name, Symbol::Flag accFlag) {
Symbol *prev{currScope().FindSymbol(name.source)};
if (!name.symbol || !prev) {
if (name.symbol) {
return DeclareOrMarkOtherAccessEntity(*name.symbol, accFlag);
} else {
return nullptr;
} else if (prev != name.symbol) {
name.symbol = prev;
}
return DeclareOrMarkOtherAccessEntity(*prev, accFlag);
}

Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
Expand Down Expand Up @@ -2990,6 +2981,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
}

Symbol *OmpAttributeVisitor::ResolveName(const parser::Name *name) {
// TODO: why is the symbol not properly resolved by name resolution?
if (auto *resolvedSymbol{
name ? GetContext().scope.FindSymbol(name->source) : nullptr}) {
name->symbol = resolvedSymbol;
Expand Down
Loading
Loading