Skip to content

Commit 29104b2

Browse files
committed
[flang][OpenMP] Use OmpDirectiveSpecification in THREADPRIVATE
Since ODS doesn't store a list of OmpObjects (i.e. not as OmpObjectList), some semantics-checking functions needed to be updated to operate on a single object at a time.
1 parent 81aaca3 commit 29104b2

File tree

10 files changed

+82
-59
lines changed

10 files changed

+82
-59
lines changed

flang/include/flang/Parser/openmp-utils.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ MAKE_CONSTR_ID(OpenMPDeclareSimdConstruct, D::OMPD_declare_simd);
4949
MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
5050
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
5151
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);
52-
MAKE_CONSTR_ID(OpenMPThreadprivate, D::OMPD_threadprivate);
5352

5453
#undef MAKE_CONSTR_ID
5554

@@ -111,8 +110,7 @@ struct DirectiveNameScope {
111110
std::is_same_v<T, OpenMPDeclareSimdConstruct> ||
112111
std::is_same_v<T, OpenMPDeclareTargetConstruct> ||
113112
std::is_same_v<T, OpenMPExecutableAllocate> ||
114-
std::is_same_v<T, OpenMPRequiresConstruct> ||
115-
std::is_same_v<T, OpenMPThreadprivate>) {
113+
std::is_same_v<T, OpenMPRequiresConstruct>) {
116114
return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id);
117115
} else {
118116
return GetFromTuple(

flang/include/flang/Parser/parse-tree.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4994,9 +4994,8 @@ struct OpenMPRequiresConstruct {
49944994

49954995
// 2.15.2 threadprivate -> THREADPRIVATE (variable-name-list)
49964996
struct OpenMPThreadprivate {
4997-
TUPLE_CLASS_BOILERPLATE(OpenMPThreadprivate);
4997+
WRAPPER_CLASS_BOILERPLATE(OpenMPThreadprivate, OmpDirectiveSpecification);
49984998
CharBlock source;
4999-
std::tuple<Verbatim, OmpObjectList> t;
50004999
};
50015000

50025001
// 2.11.3 allocate -> ALLOCATE (variable-name-list) [clause]

flang/include/flang/Semantics/openmp-utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ const parser::DataRef *GetDataRefFromObj(const parser::OmpObject &object);
5858
const parser::ArrayElement *GetArrayElementFromObj(
5959
const parser::OmpObject &object);
6060
const Symbol *GetObjectSymbol(const parser::OmpObject &object);
61-
const Symbol *GetArgumentSymbol(const parser::OmpArgument &argument);
6261
std::optional<parser::CharBlock> GetObjectSource(
6362
const parser::OmpObject &object);
63+
const Symbol *GetArgumentSymbol(const parser::OmpArgument &argument);
64+
const parser::OmpObject *GetArgumentObject(const parser::OmpArgument &argument);
6465

6566
bool IsCommonBlock(const Symbol &sym);
6667
bool IsExtendedListItem(const Symbol &sym);

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,8 +1788,11 @@ TYPE_PARSER(sourced(construct<OpenMPRequiresConstruct>(
17881788
verbatim("REQUIRES"_tok), Parser<OmpClauseList>{})))
17891789

17901790
// 2.15.2 Threadprivate directive
1791-
TYPE_PARSER(sourced(construct<OpenMPThreadprivate>(
1792-
verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{}))))
1791+
TYPE_PARSER(sourced( //
1792+
construct<OpenMPThreadprivate>(
1793+
predicated(OmpDirectiveNameParser{},
1794+
IsDirective(llvm::omp::Directive::OMPD_threadprivate)) >=
1795+
Parser<OmpDirectiveSpecification>{})))
17931796

17941797
// 2.11.3 Declarative Allocate directive
17951798
TYPE_PARSER(

flang/lib/Parser/unparse.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,12 +2599,11 @@ class UnparseVisitor {
25992599
}
26002600
void Unparse(const OpenMPThreadprivate &x) {
26012601
BeginOpenMP();
2602-
Word("!$OMP THREADPRIVATE (");
2603-
Walk(std::get<parser::OmpObjectList>(x.t));
2604-
Put(")\n");
2602+
Word("!$OMP ");
2603+
Walk(x.v);
2604+
Put("\n");
26052605
EndOpenMP();
26062606
}
2607-
26082607
bool Pre(const OmpMessageClause &x) {
26092608
Walk(x.v);
26102609
return false;

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

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -662,11 +662,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
662662
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
663663
return false;
664664
}
665-
bool Pre(const parser::OpenMPThreadprivate &x) {
666-
checker_(
667-
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_threadprivate);
668-
return false;
669-
}
670665
bool Pre(const parser::OpenMPRequiresConstruct &x) {
671666
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_requires);
672667
return false;
@@ -1299,11 +1294,16 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
12991294
}
13001295
}
13011296

1297+
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
1298+
const parser::OmpObject &object) {
1299+
common::visit(
1300+
[&](auto &&s) { CheckThreadprivateOrDeclareTargetVar(s); }, object.u);
1301+
}
1302+
13021303
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
13031304
const parser::OmpObjectList &objList) {
13041305
for (const auto &ompObject : objList.v) {
1305-
common::visit([&](auto &&s) { CheckThreadprivateOrDeclareTargetVar(s); },
1306-
ompObject.u);
1306+
CheckThreadprivateOrDeclareTargetVar(ompObject);
13071307
}
13081308
}
13091309

@@ -1363,18 +1363,20 @@ void OmpStructureChecker::Leave(const parser::OpenMPGroupprivate &x) {
13631363
dirContext_.pop_back();
13641364
}
13651365

1366-
void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) {
1367-
const auto &dir{std::get<parser::Verbatim>(c.t)};
1368-
PushContextAndClauseSets(
1369-
dir.source, llvm::omp::Directive::OMPD_threadprivate);
1366+
void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &x) {
1367+
const parser::OmpDirectiveName &dirName{x.v.DirName()};
1368+
PushContextAndClauseSets(dirName.source, dirName.v);
13701369
}
13711370

1372-
void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &c) {
1373-
const auto &dir{std::get<parser::Verbatim>(c.t)};
1374-
const auto &objectList{std::get<parser::OmpObjectList>(c.t)};
1375-
CheckSymbolNames(dir.source, objectList);
1376-
CheckVarIsNotPartOfAnotherVar(dir.source, objectList);
1377-
CheckThreadprivateOrDeclareTargetVar(objectList);
1371+
void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &x) {
1372+
const parser::OmpDirectiveSpecification &dirSpec{x.v};
1373+
for (const parser::OmpArgument &arg : x.v.Arguments().v) {
1374+
if (auto *object{GetArgumentObject(arg)}) {
1375+
CheckSymbolName(dirSpec.source, *object);
1376+
CheckVarIsNotPartOfAnotherVar(dirSpec.source, *object);
1377+
CheckThreadprivateOrDeclareTargetVar(*object);
1378+
}
1379+
}
13781380
dirContext_.pop_back();
13791381
}
13801382

@@ -1669,29 +1671,34 @@ void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) {
16691671
}
16701672
}
16711673

1672-
void OmpStructureChecker::CheckSymbolNames(
1673-
const parser::CharBlock &source, const parser::OmpObjectList &objList) {
1674-
for (const auto &ompObject : objList.v) {
1675-
common::visit(
1676-
common::visitors{
1677-
[&](const parser::Designator &designator) {
1678-
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
1679-
if (!name->symbol) {
1680-
context_.Say(source,
1681-
"The given %s directive clause has an invalid argument"_err_en_US,
1682-
ContextDirectiveAsFortran());
1683-
}
1684-
}
1685-
},
1686-
[&](const parser::Name &name) {
1687-
if (!name.symbol) {
1674+
void OmpStructureChecker::CheckSymbolName(
1675+
const parser::CharBlock &source, const parser::OmpObject &object) {
1676+
common::visit(
1677+
common::visitors{
1678+
[&](const parser::Designator &designator) {
1679+
if (const auto *name{parser::Unwrap<parser::Name>(object)}) {
1680+
if (!name->symbol) {
16881681
context_.Say(source,
16891682
"The given %s directive clause has an invalid argument"_err_en_US,
16901683
ContextDirectiveAsFortran());
16911684
}
1692-
},
1693-
},
1694-
ompObject.u);
1685+
}
1686+
},
1687+
[&](const parser::Name &name) {
1688+
if (!name.symbol) {
1689+
context_.Say(source,
1690+
"The given %s directive clause has an invalid argument"_err_en_US,
1691+
ContextDirectiveAsFortran());
1692+
}
1693+
},
1694+
},
1695+
object.u);
1696+
}
1697+
1698+
void OmpStructureChecker::CheckSymbolNames(
1699+
const parser::CharBlock &source, const parser::OmpObjectList &objList) {
1700+
for (const auto &ompObject : objList.v) {
1701+
CheckSymbolName(source, ompObject);
16951702
}
16961703
}
16971704

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,10 @@ class OmpStructureChecker
228228
const parser::OmpObjectList &objList, llvm::StringRef clause = "");
229229
void CheckThreadprivateOrDeclareTargetVar(const parser::Designator &);
230230
void CheckThreadprivateOrDeclareTargetVar(const parser::Name &);
231+
void CheckThreadprivateOrDeclareTargetVar(const parser::OmpObject &);
231232
void CheckThreadprivateOrDeclareTargetVar(const parser::OmpObjectList &);
233+
void CheckSymbolName(
234+
const parser::CharBlock &source, const parser::OmpObject &object);
232235
void CheckSymbolNames(
233236
const parser::CharBlock &source, const parser::OmpObjectList &objList);
234237
void CheckIntentInPointer(SymbolSourceMap &, const llvm::omp::Clause);

flang/lib/Semantics/openmp-utils.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ const Symbol *GetObjectSymbol(const parser::OmpObject &object) {
105105
return nullptr;
106106
}
107107

108+
std::optional<parser::CharBlock> GetObjectSource(
109+
const parser::OmpObject &object) {
110+
if (auto *name{std::get_if<parser::Name>(&object.u)}) {
111+
return name->source;
112+
} else if (auto *desg{std::get_if<parser::Designator>(&object.u)}) {
113+
return GetLastName(*desg).source;
114+
}
115+
return std::nullopt;
116+
}
117+
108118
const Symbol *GetArgumentSymbol(const parser::OmpArgument &argument) {
109119
if (auto *locator{std::get_if<parser::OmpLocator>(&argument.u)}) {
110120
if (auto *object{std::get_if<parser::OmpObject>(&locator->u)}) {
@@ -114,14 +124,12 @@ const Symbol *GetArgumentSymbol(const parser::OmpArgument &argument) {
114124
return nullptr;
115125
}
116126

117-
std::optional<parser::CharBlock> GetObjectSource(
118-
const parser::OmpObject &object) {
119-
if (auto *name{std::get_if<parser::Name>(&object.u)}) {
120-
return name->source;
121-
} else if (auto *desg{std::get_if<parser::Designator>(&object.u)}) {
122-
return GetLastName(*desg).source;
127+
const parser::OmpObject *GetArgumentObject(
128+
const parser::OmpArgument &argument) {
129+
if (auto *locator{std::get_if<parser::OmpLocator>(&argument.u)}) {
130+
return std::get_if<parser::OmpObject>(&locator->u);
123131
}
124-
return std::nullopt;
132+
return nullptr;
125133
}
126134

127135
bool IsCommonBlock(const Symbol &sym) {

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,9 +2344,14 @@ bool OmpAttributeVisitor::Pre(
23442344
}
23452345

23462346
bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
2347-
PushContext(x.source, llvm::omp::Directive::OMPD_threadprivate);
2348-
const auto &list{std::get<parser::OmpObjectList>(x.t)};
2349-
ResolveOmpObjectList(list, Symbol::Flag::OmpThreadprivate);
2347+
const parser::OmpDirectiveName &dirName{x.v.DirName()};
2348+
PushContext(dirName.source, dirName.v);
2349+
2350+
for (const parser::OmpArgument &arg : x.v.Arguments().v) {
2351+
if (auto *object{omp::GetArgumentObject(arg)}) {
2352+
ResolveOmpObject(*object, Symbol::Flag::OmpThreadprivate);
2353+
}
2354+
}
23502355
return true;
23512356
}
23522357

flang/test/Parser/OpenMP/threadprivate-blank-common-block.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
program main
55
integer :: a
66
common//a
7-
!CHECK: error: expected one of '$@ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
7+
!CHECK: error: expected end of line
88
!$omp threadprivate(//)
99
end

0 commit comments

Comments
 (0)