Skip to content

Commit c65c0e8

Browse files
authored
[flang][OpenMP] Break up CheckThreadprivateOrDeclareTargetVar, NFC (llvm#153809)
Extract the visitors into separate functions to make the code more readable. Join each message string into a single line.
1 parent 81f1b46 commit c65c0e8

File tree

2 files changed

+90
-103
lines changed

2 files changed

+90
-103
lines changed

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 87 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,110 +1081,96 @@ void OmpStructureChecker::Leave(const parser::OmpEndSectionsDirective &x) {
10811081
}
10821082
}
10831083

1084+
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
1085+
const parser::Designator &designator) {
1086+
auto *name{parser::Unwrap<parser::Name>(designator)};
1087+
// If the symbol is null, return early, CheckSymbolNames
1088+
// should have already reported the missing symbol as a
1089+
// diagnostic error
1090+
if (!name || !name->symbol) {
1091+
return;
1092+
}
1093+
1094+
llvm::omp::Directive directive{GetContext().directive};
1095+
1096+
if (name->symbol->GetUltimate().IsSubprogram()) {
1097+
if (directive == llvm::omp::Directive::OMPD_threadprivate)
1098+
context_.Say(name->source,
1099+
"The procedure name cannot be in a %s directive"_err_en_US,
1100+
ContextDirectiveAsFortran());
1101+
// TODO: Check for procedure name in declare target directive.
1102+
} else if (name->symbol->attrs().test(Attr::PARAMETER)) {
1103+
if (directive == llvm::omp::Directive::OMPD_threadprivate)
1104+
context_.Say(name->source,
1105+
"The entity with PARAMETER attribute cannot be in a %s directive"_err_en_US,
1106+
ContextDirectiveAsFortran());
1107+
else if (directive == llvm::omp::Directive::OMPD_declare_target)
1108+
context_.Warn(common::UsageWarning::OpenMPUsage, name->source,
1109+
"The entity with PARAMETER attribute is used in a %s directive"_warn_en_US,
1110+
ContextDirectiveAsFortran());
1111+
} else if (FindCommonBlockContaining(*name->symbol)) {
1112+
context_.Say(name->source,
1113+
"A variable in a %s directive cannot be an element of a common block"_err_en_US,
1114+
ContextDirectiveAsFortran());
1115+
} else if (FindEquivalenceSet(*name->symbol)) {
1116+
context_.Say(name->source,
1117+
"A variable in a %s directive cannot appear in an EQUIVALENCE statement"_err_en_US,
1118+
ContextDirectiveAsFortran());
1119+
} else if (name->symbol->test(Symbol::Flag::OmpThreadprivate) &&
1120+
directive == llvm::omp::Directive::OMPD_declare_target) {
1121+
context_.Say(name->source,
1122+
"A THREADPRIVATE variable cannot appear in a %s directive"_err_en_US,
1123+
ContextDirectiveAsFortran());
1124+
} else {
1125+
const semantics::Scope &useScope{
1126+
context_.FindScope(GetContext().directiveSource)};
1127+
const semantics::Scope &curScope = name->symbol->GetUltimate().owner();
1128+
if (!curScope.IsTopLevel()) {
1129+
const semantics::Scope &declScope =
1130+
GetProgramUnitOrBlockConstructContaining(curScope);
1131+
const semantics::Symbol *sym{
1132+
declScope.parent().FindSymbol(name->symbol->name())};
1133+
if (sym &&
1134+
(sym->has<MainProgramDetails>() || sym->has<ModuleDetails>())) {
1135+
context_.Say(name->source,
1136+
"The module name cannot be in a %s directive"_err_en_US,
1137+
ContextDirectiveAsFortran());
1138+
} else if (!IsSaved(*name->symbol) &&
1139+
declScope.kind() != Scope::Kind::MainProgram &&
1140+
declScope.kind() != Scope::Kind::Module) {
1141+
context_.Say(name->source,
1142+
"A variable that appears in a %s directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly"_err_en_US,
1143+
ContextDirectiveAsFortran());
1144+
} else if (useScope != declScope) {
1145+
context_.Say(name->source,
1146+
"The %s directive and the common block or variable in it must appear in the same declaration section of a scoping unit"_err_en_US,
1147+
ContextDirectiveAsFortran());
1148+
}
1149+
}
1150+
}
1151+
}
1152+
1153+
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
1154+
const parser::Name &name) {
1155+
if (!name.symbol) {
1156+
return;
1157+
}
1158+
1159+
if (auto *cb{name.symbol->detailsIf<CommonBlockDetails>()}) {
1160+
for (const auto &obj : cb->objects()) {
1161+
if (FindEquivalenceSet(*obj)) {
1162+
context_.Say(name.source,
1163+
"A variable in a %s directive cannot appear in an EQUIVALENCE statement (variable '%s' from common block '/%s/')"_err_en_US,
1164+
ContextDirectiveAsFortran(), obj->name(), name.symbol->name());
1165+
}
1166+
}
1167+
}
1168+
}
1169+
10841170
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
10851171
const parser::OmpObjectList &objList) {
10861172
for (const auto &ompObject : objList.v) {
1087-
common::visit(
1088-
common::visitors{
1089-
[&](const parser::Designator &) {
1090-
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
1091-
// The symbol is null, return early, CheckSymbolNames
1092-
// should have already reported the missing symbol as a
1093-
// diagnostic error
1094-
if (!name->symbol) {
1095-
return;
1096-
}
1097-
1098-
if (name->symbol->GetUltimate().IsSubprogram()) {
1099-
if (GetContext().directive ==
1100-
llvm::omp::Directive::OMPD_threadprivate)
1101-
context_.Say(name->source,
1102-
"The procedure name cannot be in a %s "
1103-
"directive"_err_en_US,
1104-
ContextDirectiveAsFortran());
1105-
// TODO: Check for procedure name in declare target directive.
1106-
} else if (name->symbol->attrs().test(Attr::PARAMETER)) {
1107-
if (GetContext().directive ==
1108-
llvm::omp::Directive::OMPD_threadprivate)
1109-
context_.Say(name->source,
1110-
"The entity with PARAMETER attribute cannot be in a %s "
1111-
"directive"_err_en_US,
1112-
ContextDirectiveAsFortran());
1113-
else if (GetContext().directive ==
1114-
llvm::omp::Directive::OMPD_declare_target)
1115-
context_.Warn(common::UsageWarning::OpenMPUsage,
1116-
name->source,
1117-
"The entity with PARAMETER attribute is used in a %s directive"_warn_en_US,
1118-
ContextDirectiveAsFortran());
1119-
} else if (FindCommonBlockContaining(*name->symbol)) {
1120-
context_.Say(name->source,
1121-
"A variable in a %s directive cannot be an element of a "
1122-
"common block"_err_en_US,
1123-
ContextDirectiveAsFortran());
1124-
} else if (FindEquivalenceSet(*name->symbol)) {
1125-
context_.Say(name->source,
1126-
"A variable in a %s directive cannot appear in an "
1127-
"EQUIVALENCE statement"_err_en_US,
1128-
ContextDirectiveAsFortran());
1129-
} else if (name->symbol->test(Symbol::Flag::OmpThreadprivate) &&
1130-
GetContext().directive ==
1131-
llvm::omp::Directive::OMPD_declare_target) {
1132-
context_.Say(name->source,
1133-
"A THREADPRIVATE variable cannot appear in a %s "
1134-
"directive"_err_en_US,
1135-
ContextDirectiveAsFortran());
1136-
} else {
1137-
const semantics::Scope &useScope{
1138-
context_.FindScope(GetContext().directiveSource)};
1139-
const semantics::Scope &curScope =
1140-
name->symbol->GetUltimate().owner();
1141-
if (!curScope.IsTopLevel()) {
1142-
const semantics::Scope &declScope =
1143-
GetProgramUnitOrBlockConstructContaining(curScope);
1144-
const semantics::Symbol *sym{
1145-
declScope.parent().FindSymbol(name->symbol->name())};
1146-
if (sym &&
1147-
(sym->has<MainProgramDetails>() ||
1148-
sym->has<ModuleDetails>())) {
1149-
context_.Say(name->source,
1150-
"The module name cannot be in a %s "
1151-
"directive"_err_en_US,
1152-
ContextDirectiveAsFortran());
1153-
} else if (!IsSaved(*name->symbol) &&
1154-
declScope.kind() != Scope::Kind::MainProgram &&
1155-
declScope.kind() != Scope::Kind::Module) {
1156-
context_.Say(name->source,
1157-
"A variable that appears in a %s directive must be "
1158-
"declared in the scope of a module or have the SAVE "
1159-
"attribute, either explicitly or "
1160-
"implicitly"_err_en_US,
1161-
ContextDirectiveAsFortran());
1162-
} else if (useScope != declScope) {
1163-
context_.Say(name->source,
1164-
"The %s directive and the common block or variable "
1165-
"in it must appear in the same declaration section "
1166-
"of a scoping unit"_err_en_US,
1167-
ContextDirectiveAsFortran());
1168-
}
1169-
}
1170-
}
1171-
}
1172-
},
1173-
[&](const parser::Name &name) {
1174-
if (name.symbol) {
1175-
if (auto *cb{name.symbol->detailsIf<CommonBlockDetails>()}) {
1176-
for (const auto &obj : cb->objects()) {
1177-
if (FindEquivalenceSet(*obj)) {
1178-
context_.Say(name.source,
1179-
"A variable in a %s directive cannot appear in an EQUIVALENCE statement (variable '%s' from common block '/%s/')"_err_en_US,
1180-
ContextDirectiveAsFortran(), obj->name(),
1181-
name.symbol->name());
1182-
}
1183-
}
1184-
}
1185-
}
1186-
},
1187-
},
1173+
common::visit([&](auto &&s) { CheckThreadprivateOrDeclareTargetVar(s); },
11881174
ompObject.u);
11891175
}
11901176
}

flang/lib/Semantics/check-omp-structure.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,9 @@ class OmpStructureChecker
222222
const parser::OmpObject &obj, llvm::StringRef clause = "");
223223
void CheckVarIsNotPartOfAnotherVar(const parser::CharBlock &source,
224224
const parser::OmpObjectList &objList, llvm::StringRef clause = "");
225-
void CheckThreadprivateOrDeclareTargetVar(
226-
const parser::OmpObjectList &objList);
225+
void CheckThreadprivateOrDeclareTargetVar(const parser::Designator &);
226+
void CheckThreadprivateOrDeclareTargetVar(const parser::Name &);
227+
void CheckThreadprivateOrDeclareTargetVar(const parser::OmpObjectList &);
227228
void CheckSymbolNames(
228229
const parser::CharBlock &source, const parser::OmpObjectList &objList);
229230
void CheckIntentInPointer(SymbolSourceMap &, const llvm::omp::Clause);

0 commit comments

Comments
 (0)