@@ -170,20 +170,22 @@ bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) {
170
170
return false ;
171
171
}
172
172
173
+ void OmpStructureChecker::CheckMultipleOccurrence (
174
+ semantics::UnorderedSymbolSet &listVars,
175
+ const std::list<parser::Name> &nameList, const parser::CharBlock &item,
176
+ const std::string &clauseName) {
177
+ for (auto const &var : nameList) {
178
+ if (llvm::is_contained (listVars, *(var.symbol ))) {
179
+ context_.Say (item,
180
+ " List item '%s' present at multiple %s clauses" _err_en_US,
181
+ var.ToString (), clauseName);
182
+ }
183
+ listVars.insert (*(var.symbol ));
184
+ }
185
+ }
186
+
173
187
void OmpStructureChecker::CheckMultListItems () {
174
188
semantics::UnorderedSymbolSet listVars;
175
- auto checkMultipleOcurrence = [&](const std::list<parser::Name> &nameList,
176
- const parser::CharBlock &item,
177
- const std::string &clauseName) {
178
- for (auto const &var : nameList) {
179
- if (llvm::is_contained (listVars, *(var.symbol ))) {
180
- context_.Say (item,
181
- " List item '%s' present at multiple %s clauses" _err_en_US,
182
- var.ToString (), clauseName);
183
- }
184
- listVars.insert (*(var.symbol ));
185
- }
186
- };
187
189
188
190
// Aligned clause
189
191
auto alignedClauses{FindClauses (llvm::omp::Clause::OMPC_aligned)};
@@ -216,7 +218,8 @@ void OmpStructureChecker::CheckMultListItems() {
216
218
}
217
219
}
218
220
}
219
- checkMultipleOcurrence (alignedNameList, itr->second ->source , " ALIGNED" );
221
+ CheckMultipleOccurrence (
222
+ listVars, alignedNameList, itr->second ->source , " ALIGNED" );
220
223
}
221
224
222
225
// Nontemporal clause
@@ -226,7 +229,8 @@ void OmpStructureChecker::CheckMultListItems() {
226
229
const auto &nontempClause{
227
230
std::get<parser::OmpClause::Nontemporal>(itr->second ->u )};
228
231
const auto &nontempNameList{nontempClause.v };
229
- checkMultipleOcurrence (nontempNameList, itr->second ->source , " NONTEMPORAL" );
232
+ CheckMultipleOccurrence (
233
+ listVars, nontempNameList, itr->second ->source , " NONTEMPORAL" );
230
234
}
231
235
}
232
236
@@ -2000,10 +2004,8 @@ CHECK_SIMPLE_CLAUSE(UnifiedSharedMemory, OMPC_unified_shared_memory)
2000
2004
CHECK_SIMPLE_CLAUSE (Uniform, OMPC_uniform)
2001
2005
CHECK_SIMPLE_CLAUSE (Unknown, OMPC_unknown)
2002
2006
CHECK_SIMPLE_CLAUSE (Untied, OMPC_untied)
2003
- CHECK_SIMPLE_CLAUSE (UseDevicePtr, OMPC_use_device_ptr)
2004
2007
CHECK_SIMPLE_CLAUSE (UsesAllocators, OMPC_uses_allocators)
2005
2008
CHECK_SIMPLE_CLAUSE (Update, OMPC_update)
2006
- CHECK_SIMPLE_CLAUSE (UseDeviceAddr, OMPC_use_device_addr)
2007
2009
CHECK_SIMPLE_CLAUSE (Write, OMPC_write)
2008
2010
CHECK_SIMPLE_CLAUSE (Init, OMPC_init)
2009
2011
CHECK_SIMPLE_CLAUSE (Use, OMPC_use)
@@ -2618,6 +2620,89 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) {
2618
2620
currSymbols, llvm::omp::Clause::OMPC_copyin);
2619
2621
}
2620
2622
2623
+ void OmpStructureChecker::CheckStructureElement (
2624
+ const parser::OmpObjectList &ompObjectList,
2625
+ const llvm::omp::Clause clause) {
2626
+ for (const auto &ompObject : ompObjectList.v ) {
2627
+ common::visit (
2628
+ common::visitors{
2629
+ [&](const parser::Designator &designator) {
2630
+ if (const auto *dataRef{
2631
+ std::get_if<parser::DataRef>(&designator.u )}) {
2632
+ if (parser::Unwrap<parser::StructureComponent>(ompObject)) {
2633
+ context_.Say (GetContext ().clauseSource ,
2634
+ " A variable that is part of another variable "
2635
+ " (structure element) cannot appear on the %s "
2636
+ " %s clause" _err_en_US,
2637
+ ContextDirectiveAsFortran (),
2638
+ parser::ToUpperCaseLetters (getClauseName (clause).str ()));
2639
+ }
2640
+ }
2641
+ },
2642
+ [&](const parser::Name &name) {},
2643
+ },
2644
+ ompObject.u );
2645
+ }
2646
+ return ;
2647
+ }
2648
+
2649
+ void OmpStructureChecker::Enter (const parser::OmpClause::UseDevicePtr &x) {
2650
+ CheckStructureElement (x.v , llvm::omp::Clause::OMPC_use_device_ptr);
2651
+ CheckAllowed (llvm::omp::Clause::OMPC_use_device_ptr);
2652
+ SymbolSourceMap currSymbols;
2653
+ GetSymbolsInObjectList (x.v , currSymbols);
2654
+ semantics::UnorderedSymbolSet listVars;
2655
+ auto useDevicePtrClauses{FindClauses (llvm::omp::Clause::OMPC_use_device_ptr)};
2656
+ for (auto itr = useDevicePtrClauses.first ; itr != useDevicePtrClauses.second ;
2657
+ ++itr) {
2658
+ const auto &useDevicePtrClause{
2659
+ std::get<parser::OmpClause::UseDevicePtr>(itr->second ->u )};
2660
+ const auto &useDevicePtrList{useDevicePtrClause.v };
2661
+ std::list<parser::Name> useDevicePtrNameList;
2662
+ for (const auto &ompObject : useDevicePtrList.v ) {
2663
+ if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
2664
+ if (name->symbol ) {
2665
+ if (!(IsBuiltinCPtr (*(name->symbol )))) {
2666
+ context_.Say (itr->second ->source ,
2667
+ " '%s' in USE_DEVICE_PTR clause must be of type C_PTR" _err_en_US,
2668
+ name->ToString ());
2669
+ } else {
2670
+ useDevicePtrNameList.push_back (*name);
2671
+ }
2672
+ }
2673
+ }
2674
+ }
2675
+ CheckMultipleOccurrence (
2676
+ listVars, useDevicePtrNameList, itr->second ->source , " USE_DEVICE_PTR" );
2677
+ }
2678
+ }
2679
+
2680
+ void OmpStructureChecker::Enter (const parser::OmpClause::UseDeviceAddr &x) {
2681
+ CheckStructureElement (x.v , llvm::omp::Clause::OMPC_use_device_addr);
2682
+ CheckAllowed (llvm::omp::Clause::OMPC_use_device_addr);
2683
+ SymbolSourceMap currSymbols;
2684
+ GetSymbolsInObjectList (x.v , currSymbols);
2685
+ semantics::UnorderedSymbolSet listVars;
2686
+ auto useDeviceAddrClauses{
2687
+ FindClauses (llvm::omp::Clause::OMPC_use_device_addr)};
2688
+ for (auto itr = useDeviceAddrClauses.first ;
2689
+ itr != useDeviceAddrClauses.second ; ++itr) {
2690
+ const auto &useDeviceAddrClause{
2691
+ std::get<parser::OmpClause::UseDeviceAddr>(itr->second ->u )};
2692
+ const auto &useDeviceAddrList{useDeviceAddrClause.v };
2693
+ std::list<parser::Name> useDeviceAddrNameList;
2694
+ for (const auto &ompObject : useDeviceAddrList.v ) {
2695
+ if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
2696
+ if (name->symbol ) {
2697
+ useDeviceAddrNameList.push_back (*name);
2698
+ }
2699
+ }
2700
+ }
2701
+ CheckMultipleOccurrence (listVars, useDeviceAddrNameList,
2702
+ itr->second ->source , " USE_DEVICE_ADDR" );
2703
+ }
2704
+ }
2705
+
2621
2706
llvm::StringRef OmpStructureChecker::getClauseName (llvm::omp::Clause clause) {
2622
2707
return llvm::omp::getOpenMPClauseName (clause);
2623
2708
}
0 commit comments