@@ -529,13 +529,45 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
529529 void Post (const parser::EorLabel &eorLabel) { CheckSourceLabel (eorLabel.v ); }
530530
531531 void Post (const parser::OmpMapClause &x) {
532+ Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
533+ if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.t )}) {
534+ using Type = parser::OmpMapType::Type;
535+ const Type &type{std::get<Type>(maptype->t )};
536+ switch (type) {
537+ case Type::To:
538+ ompFlag = Symbol::Flag::OmpMapTo;
539+ break ;
540+ case Type::From:
541+ ompFlag = Symbol::Flag::OmpMapFrom;
542+ break ;
543+ case Type::Tofrom:
544+ ompFlag = Symbol::Flag::OmpMapToFrom;
545+ break ;
546+ case Type::Alloc:
547+ ompFlag = Symbol::Flag::OmpMapAlloc;
548+ break ;
549+ case Type::Release:
550+ ompFlag = Symbol::Flag::OmpMapRelease;
551+ break ;
552+ case Type::Delete:
553+ ompFlag = Symbol::Flag::OmpMapDelete;
554+ break ;
555+ default :
556+ assert (false && " Unsupported map-type" );
557+ break ;
558+ }
559+ }
532560 const auto &ompObjList{std::get<parser::OmpObjectList>(x.t )};
533561 for (const auto &ompObj : ompObjList.v ) {
534562 common::visit (
535563 common::visitors{
536564 [&](const parser::Designator &designator) {
537565 if (const auto *name{
538566 semantics::getDesignatorNameIfDataRef (designator)}) {
567+ if (name->symbol ) {
568+ name->symbol ->set (ompFlag);
569+ AddToContextObjectWithDSA (*name->symbol , ompFlag);
570+ }
539571 if (name->symbol &&
540572 semantics::IsAssumedSizeArray (*name->symbol )) {
541573 context_.Say (designator.source ,
@@ -1908,6 +1940,27 @@ void OmpAttributeVisitor::ResolveOmpObject(
19081940 if (const auto *name{
19091941 semantics::getDesignatorNameIfDataRef (designator)}) {
19101942 if (auto *symbol{ResolveOmp (*name, ompFlag, currScope ())}) {
1943+ auto checkExclusivelists =
1944+ [&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
1945+ Symbol *symbol2, Symbol::Flag secondOmpFlag) {
1946+ if ((symbol1->test (firstOmpFlag) &&
1947+ symbol2->test (secondOmpFlag)) ||
1948+ (symbol1->test (secondOmpFlag) &&
1949+ symbol2->test (firstOmpFlag))) {
1950+ context_.Say (designator.source ,
1951+ " Variable '%s' may not "
1952+ " appear on both %s and %s "
1953+ " clauses on a %s construct" _err_en_US,
1954+ symbol2->name (),
1955+ const_cast <Symbol *>(symbol1)->OmpFlagToClauseName (
1956+ firstOmpFlag),
1957+ symbol2->OmpFlagToClauseName (secondOmpFlag),
1958+ parser::ToUpperCaseLetters (
1959+ llvm::omp::getOpenMPDirectiveName (
1960+ GetContext ().directive )
1961+ .str ()));
1962+ }
1963+ };
19111964 if (dataCopyingAttributeFlags.test (ompFlag)) {
19121965 CheckDataCopyingClause (*name, *symbol, ompFlag);
19131966 } else {
@@ -1943,28 +1996,37 @@ void OmpAttributeVisitor::ResolveOmpObject(
19431996 GetContext ().directive )
19441997 .str ()));
19451998 }
1946- if ((GetContext ().directive ==
1947- llvm::omp::Directive::OMPD_target_data) &&
1948- (((ompFlag == Symbol::Flag::OmpUseDevicePtr) &&
1949- symbol->test (Symbol::Flag::OmpUseDeviceAddr)) ||
1950- ((ompFlag == Symbol::Flag::OmpUseDeviceAddr) &&
1951- symbol->test (Symbol::Flag::OmpUseDevicePtr)))) {
1952- context_.Say (designator.source ,
1953- " Variable '%s' may not "
1954- " appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR "
1955- " clauses on a TARGET DATA construct" _err_en_US,
1956- symbol->name ());
1999+ if (GetContext ().directive ==
2000+ llvm::omp::Directive::OMPD_target_data) {
2001+ checkExclusivelists (symbol, Symbol::Flag::OmpUseDevicePtr,
2002+ symbol, Symbol::Flag::OmpUseDeviceAddr);
19572003 }
1958- if (llvm::omp::allDistributeSet.test (GetContext ().directive ) &&
1959- (((ompFlag == Symbol::Flag::OmpFirstPrivate) &&
1960- symbol->test (Symbol::Flag::OmpLastPrivate)) ||
1961- ((ompFlag == Symbol::Flag::OmpLastPrivate) &&
1962- symbol->test (Symbol::Flag::OmpFirstPrivate)))) {
1963- context_.Say (designator.source ,
1964- " Variable '%s' may not "
1965- " appear on both FIRSTPRIVATE and LASTPRIVATE "
1966- " clauses on a DISTRIBUTE construct" _err_en_US,
1967- symbol->name ());
2004+ if (llvm::omp::allDistributeSet.test (GetContext ().directive )) {
2005+ checkExclusivelists (symbol, Symbol::Flag::OmpFirstPrivate,
2006+ symbol, Symbol::Flag::OmpLastPrivate);
2007+ }
2008+ if (llvm::omp::allTargetSet.test (GetContext ().directive )) {
2009+ const auto *hostAssocSym{symbol};
2010+ if (const auto *details{
2011+ symbol->detailsIf <HostAssocDetails>()}) {
2012+ hostAssocSym = &details->symbol ();
2013+ }
2014+ Symbol::Flag dataMappingAttributeFlags[] = {
2015+ Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
2016+ Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapAlloc,
2017+ Symbol::Flag::OmpMapRelease, Symbol::Flag::OmpMapDelete};
2018+
2019+ Symbol::Flag dataSharingAttributeFlags[] = {
2020+ Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
2021+ Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
2022+ Symbol::Flag::OmpLinear};
2023+
2024+ for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
2025+ for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
2026+ checkExclusivelists (
2027+ hostAssocSym, ompFlag1, symbol, ompFlag2);
2028+ }
2029+ }
19682030 }
19692031 }
19702032 } else {
0 commit comments