[flang][OpenMP] Add support for getting parent context and clauses and modify the relevant sema checks to use the new functions.

Differential Revision: https://reviews.llvm.org/D98580
This commit is contained in:
Arnamoy Bhattacharyya 2021-03-13 09:27:53 -05:00
parent 04eec6f881
commit 3fc9ca87f1
2 changed files with 24 additions and 8 deletions

View File

@ -150,6 +150,11 @@ protected:
return dirContext_.back();
}
DirectiveContext &GetContextParent() {
CHECK(dirContext_.size() >= 2);
return dirContext_[dirContext_.size() - 2];
}
void SetContextClause(const PC &clause) {
GetContext().clauseSource = clause.source;
GetContext().clause = &clause;
@ -198,6 +203,7 @@ protected:
GetContext().actualClauses.push_back(type);
}
// Check if the given clause is present in the current context
const PC *FindClause(C type) {
auto it{GetContext().clauseInfo.find(type)};
if (it != GetContext().clauseInfo.end()) {
@ -206,6 +212,15 @@ protected:
return nullptr;
}
// Check if the given clause is present in the parent context
const PC *FindClauseParent(C type) {
auto it{GetContextParent().clauseInfo.find(type)};
if (it != GetContextParent().clauseInfo.end()) {
return it->second;
}
return nullptr;
}
std::pair<typename ClauseMapTy::iterator, typename ClauseMapTy::iterator>
FindClauses(C type) {
auto it{GetContext().clauseInfo.equal_range(type)};

View File

@ -131,7 +131,7 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting(
const parser::CharBlock &source, const OmpDirectiveSet &set) {
// set contains all the invalid closely nested directives
// for the given directive (`source` here)
if (CurrentDirectiveIsNested() && set.test(GetContext().directive)) {
if (CurrentDirectiveIsNested() && set.test(GetContextParent().directive)) {
context_.Say(source,
"A worksharing region may not be closely nested inside a "
"worksharing, explicit task, taskloop, critical, ordered, atomic, or "
@ -158,9 +158,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
CheckMatching<parser::OmpLoopDirective>(beginDir, endDir);
}
if (beginDir.v != llvm::omp::Directive::OMPD_do) {
PushContextAndClauseSets(beginDir.source, beginDir.v);
} else {
PushContextAndClauseSets(beginDir.source, beginDir.v);
if (beginDir.v == llvm::omp::Directive::OMPD_do) {
// 2.7.1 do-clause -> private-clause |
// firstprivate-clause |
// lastprivate-clause |
@ -181,7 +181,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
llvm::omp::Directive::OMPD_ordered,
llvm::omp::Directive::OMPD_atomic,
llvm::omp::Directive::OMPD_master});
PushContextAndClauseSets(beginDir.source, llvm::omp::Directive::OMPD_do);
}
SetLoopInfo(x);
@ -318,15 +317,17 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
CheckMatching<parser::OmpBlockDirective>(beginDir, endDir);
PushContextAndClauseSets(beginDir.source, beginDir.v);
// TODO: This check needs to be extended while implementing nesting of regions
// checks.
if (beginDir.v == llvm::omp::Directive::OMPD_single) {
HasInvalidWorksharingNesting(
beginDir.source, {llvm::omp::Directive::OMPD_do});
}
CheckIfDoOrderedClause(beginDir);
if (CurrentDirectiveIsNested())
CheckIfDoOrderedClause(beginDir);
PushContextAndClauseSets(beginDir.source, beginDir.v);
CheckNoBranching(block, beginDir.v, beginDir.source);
switch (beginDir.v) {
@ -342,7 +343,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
void OmpStructureChecker::CheckIfDoOrderedClause(
const parser::OmpBlockDirective &blkDirective) {
if (blkDirective.v == llvm::omp::OMPD_ordered) {
if (!FindClause(llvm::omp::Clause::OMPC_ordered)) {
if (!FindClauseParent(llvm::omp::Clause::OMPC_ordered)) {
context_.Say(blkDirective.source,
"The ORDERED clause must be present on the loop"
" construct if any ORDERED region ever binds"