Skip to content

Commit ad5778f

Browse files
authored
[flang][OpenMP] Use OmpDirectiveSpecification in THREADPRIVATE (#159632)
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 bd67b8f commit ad5778f

File tree

10 files changed

+111
-63
lines changed

10 files changed

+111
-63
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

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

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

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

50015001
// 2.15.2 threadprivate -> THREADPRIVATE (variable-name-list)
50025002
struct OpenMPThreadprivate {
5003-
TUPLE_CLASS_BOILERPLATE(OpenMPThreadprivate);
5003+
WRAPPER_CLASS_BOILERPLATE(OpenMPThreadprivate, OmpDirectiveSpecification);
50045004
CharBlock source;
5005-
std::tuple<Verbatim, OmpObjectList> t;
50065005
};
50075006

50085007
// 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
@@ -1791,8 +1791,11 @@ TYPE_PARSER(sourced(construct<OpenMPRequiresConstruct>(
17911791
verbatim("REQUIRES"_tok), Parser<OmpClauseList>{})))
17921792

17931793
// 2.15.2 Threadprivate directive
1794-
TYPE_PARSER(sourced(construct<OpenMPThreadprivate>(
1795-
verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{}))))
1794+
TYPE_PARSER(sourced( //
1795+
construct<OpenMPThreadprivate>(
1796+
predicated(OmpDirectiveNameParser{},
1797+
IsDirective(llvm::omp::Directive::OMPD_threadprivate)) >=
1798+
Parser<OmpDirectiveSpecification>{})))
17961799

17971800
// 2.11.3 Declarative Allocate directive
17981801
TYPE_PARSER(

flang/lib/Parser/unparse.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,12 +2611,11 @@ class UnparseVisitor {
26112611
}
26122612
void Unparse(const OpenMPThreadprivate &x) {
26132613
BeginOpenMP();
2614-
Word("!$OMP THREADPRIVATE (");
2615-
Walk(std::get<parser::OmpObjectList>(x.t));
2616-
Put(")\n");
2614+
Word("!$OMP ");
2615+
Walk(x.v);
2616+
Put("\n");
26172617
EndOpenMP();
26182618
}
2619-
26202619
bool Pre(const OmpMessageClause &x) {
26212620
Walk(x.v);
26222621
return false;

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

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
665665
checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
666666
return false;
667667
}
668-
bool Pre(const parser::OpenMPThreadprivate &x) {
669-
checker_(
670-
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_threadprivate);
671-
return false;
672-
}
673668
bool Pre(const parser::OpenMPRequiresConstruct &x) {
674669
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_requires);
675670
return false;
@@ -1294,15 +1289,20 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
12941289
}
12951290
}
12961291

1292+
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
1293+
const parser::OmpObject &object) {
1294+
common::visit( //
1295+
common::visitors{
1296+
[&](auto &&s) { CheckThreadprivateOrDeclareTargetVar(s); },
1297+
[&](const parser::OmpObject::Invalid &invalid) {},
1298+
},
1299+
object.u);
1300+
}
1301+
12971302
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
12981303
const parser::OmpObjectList &objList) {
12991304
for (const auto &ompObject : objList.v) {
1300-
common::visit( //
1301-
common::visitors{
1302-
[&](auto &&s) { CheckThreadprivateOrDeclareTargetVar(s); },
1303-
[&](const parser::OmpObject::Invalid &invalid) {},
1304-
},
1305-
ompObject.u);
1305+
CheckThreadprivateOrDeclareTargetVar(ompObject);
13061306
}
13071307
}
13081308

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

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

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

@@ -1672,30 +1674,35 @@ void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) {
16721674
}
16731675
}
16741676

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

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
@@ -2342,9 +2342,14 @@ bool OmpAttributeVisitor::Pre(
23422342
}
23432343

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
2+
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
module m
5+
implicit none
6+
integer :: a, b
7+
common /blk/ a
8+
9+
!$omp threadprivate(/blk/, b)
10+
11+
end module
12+
13+
!UNPARSE: MODULE m
14+
!UNPARSE: IMPLICIT NONE
15+
!UNPARSE: INTEGER a, b
16+
!UNPARSE: COMMON /blk/a
17+
!UNPARSE: !$OMP THREADPRIVATE(/blk/, b)
18+
!UNPARSE: END MODULE
19+
20+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPThreadprivate -> OmpDirectiveSpecification
21+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = threadprivate
22+
!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Name = 'blk'
23+
!PARSE-TREE: | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'b'
24+
!PARSE-TREE: | OmpClauseList ->
25+
!PARSE-TREE: | Flags = None

0 commit comments

Comments
 (0)