[flang][OpenMP] Parse OpenMP 6.0 syntax of INIT clause (#171702)

This includes `FR(...)` for foreign runtime identifiers and `ATTR(...)`
for extensions. Do not store string runtime ids as character literals in
the AST. Use parser::Expr instead, since lowering would require
evaluate::Expr for these ids, and we get evaluate::Expr from
parser::Expr automatically.

Use OpenMP 6.0 naming for AST nodes (since it's the "current" one).
This commit is contained in:
Krzysztof Parzyszek 2025-12-11 08:08:14 -06:00 committed by GitHub
parent b2dae2ba6e
commit dd63dff83a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 196 additions and 212 deletions

View File

@ -495,6 +495,9 @@ public:
READ_FEATURE(OmpOrderClause::Ordering)
READ_FEATURE(OmpOrderModifier)
READ_FEATURE(OmpOrderModifier::Value)
READ_FEATURE(OmpPreferenceSelector)
READ_FEATURE(OmpPreferenceSpecification)
READ_FEATURE(OmpPreferType)
READ_FEATURE(OmpProcBindClause)
READ_FEATURE(OmpProcBindClause::AffinityPolicy)
READ_FEATURE(OmpReductionClause)
@ -509,8 +512,6 @@ public:
READ_FEATURE(OmpScheduleClause)
READ_FEATURE(OmpScheduleClause::Kind)
READ_FEATURE(OmpScheduleClause::Modifier)
READ_FEATURE(OmpInteropRuntimeIdentifier)
READ_FEATURE(OmpInteropPreference)
READ_FEATURE(OmpInteropType)
READ_FEATURE(OmpInteropType::Value)
READ_FEATURE(OmpInitClause)

View File

@ -627,8 +627,6 @@ public:
NODE(parser, OmpInitializerExpression)
NODE(parser, OmpInReductionClause)
NODE(OmpInReductionClause, Modifier)
NODE(parser, OmpInteropPreference)
NODE(parser, OmpInteropRuntimeIdentifier)
NODE(parser, OmpInteropType)
NODE_ENUM(OmpInteropType, Value)
NODE(parser, OmpIteration)
@ -681,6 +679,9 @@ public:
NODE(parser, OmpOrderModifier)
NODE_ENUM(OmpOrderModifier, Value)
NODE(parser, OmpOtherwiseClause)
NODE(parser, OmpPreferenceSelector)
NODE(parser, OmpPreferenceSpecification)
NODE(parser, OmpPreferType)
NODE(parser, OmpPrescriptiveness)
NODE_ENUM(OmpPrescriptiveness, Value)
NODE(parser, OmpPresentModifier)

View File

@ -4031,27 +4031,45 @@ struct OmpFallbackModifier {
WRAPPER_CLASS_BOILERPLATE(OmpFallbackModifier, Value);
};
// REF: [5.1:217-220], [5.2:293-294]
// Ref: [6.0:470-471]
//
// OmpInteropRuntimeIdentifier -> // since 5.2
// CharLiteralConstant || ScalarIntConstantExpr
struct OmpInteropRuntimeIdentifier {
UNION_CLASS_BOILERPLATE(OmpInteropRuntimeIdentifier);
std::variant<CharLiteralConstant, ScalarIntConstantExpr> u;
// preference-selector -> // since 6.0
// FR(foreign-runtime-identifier) |
// ATTR(preference-property-extension, ...)
struct OmpPreferenceSelector {
UNION_CLASS_BOILERPLATE(OmpPreferenceSelector);
using ForeignRuntimeIdentifier = common::Indirection<Expr>;
using PreferencePropertyExtension = common::Indirection<Expr>;
using Extensions = std::list<PreferencePropertyExtension>;
std::variant<ForeignRuntimeIdentifier, Extensions> u;
};
// REF: [5.1:217-220], [5.2:293-294]
// Ref: [6.0:470-471]
//
// OmpInteropPreference -> // since 5.2
// ([OmpRuntimeIdentifier, ...])
struct OmpInteropPreference {
// preference-specification ->
// {preference-selector...} | // since 6.0
// foreign-runtime-identifier // since 5.1
struct OmpPreferenceSpecification {
UNION_CLASS_BOILERPLATE(OmpPreferenceSpecification);
using ForeignRuntimeIdentifier =
OmpPreferenceSelector::ForeignRuntimeIdentifier;
std::variant<std::list<OmpPreferenceSelector>, ForeignRuntimeIdentifier> u;
};
// REF: [5.1:217-220], [5.2:293-294], [6.0:470-471]
//
// prefer-type -> // since 5.1
// PREFER_TYPE(preference-specification...)
struct OmpPreferType {
WRAPPER_CLASS_BOILERPLATE(
OmpInteropPreference, std::list<OmpInteropRuntimeIdentifier>);
OmpPreferType, std::list<OmpPreferenceSpecification>);
};
// REF: [5.1:217-220], [5.2:293-294]
// REF: [5.1:217-220], [5.2:293-294], [6.0:470-471]
//
// InteropType -> target || targetsync // since 5.2
// interop-type -> // since 5.1
// TARGET |
// TARGETSYNC
// There can be at most only two interop-type.
struct OmpInteropType {
ENUM_CLASS(Value, Target, TargetSync)
@ -4997,7 +5015,7 @@ struct OmpWhenClause {
// There can be at most only two interop-type.
struct OmpInitClause {
TUPLE_CLASS_BOILERPLATE(OmpInitClause);
MODIFIER_BOILERPLATE(OmpInteropPreference, OmpInteropType);
MODIFIER_BOILERPLATE(OmpPreferType, OmpInteropType);
std::tuple<MODIFIERS(), OmpObject> t;
};

View File

@ -85,7 +85,6 @@ DECLARE_DESCRIPTOR(parser::OmpDimsModifier);
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
DECLARE_DESCRIPTOR(parser::OmpExpectation);
DECLARE_DESCRIPTOR(parser::OmpFallbackModifier);
DECLARE_DESCRIPTOR(parser::OmpInteropPreference);
DECLARE_DESCRIPTOR(parser::OmpInteropType);
DECLARE_DESCRIPTOR(parser::OmpIterator);
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
@ -96,6 +95,7 @@ DECLARE_DESCRIPTOR(parser::OmpMapType);
DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier);
DECLARE_DESCRIPTOR(parser::OmpOrderModifier);
DECLARE_DESCRIPTOR(parser::OmpOrderingModifier);
DECLARE_DESCRIPTOR(parser::OmpPreferType);
DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness);
DECLARE_DESCRIPTOR(parser::OmpPresentModifier);
DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier);

View File

@ -831,13 +831,6 @@ TYPE_PARSER(construct<OmpFallbackModifier>("FALLBACK"_tok >>
"DEFAULT_MEM" >> pure(OmpFallbackModifier::Value::Default_Mem) ||
"NULL" >> pure(OmpFallbackModifier::Value::Null))))
TYPE_PARSER(construct<OmpInteropRuntimeIdentifier>(
construct<OmpInteropRuntimeIdentifier>(charLiteralConstant) ||
construct<OmpInteropRuntimeIdentifier>(scalarIntConstantExpr)))
TYPE_PARSER(construct<OmpInteropPreference>(verbatim("PREFER_TYPE"_tok) >>
parenthesized(nonemptyList(Parser<OmpInteropRuntimeIdentifier>{}))))
TYPE_PARSER(construct<OmpInteropType>(
"TARGETSYNC" >> pure(OmpInteropType::Value::TargetSync) ||
"TARGET" >> pure(OmpInteropType::Value::Target)))
@ -898,6 +891,20 @@ TYPE_PARSER(construct<OmpOrderingModifier>(
"NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) ||
"SIMD" >> pure(OmpOrderingModifier::Value::Simd)))
TYPE_PARSER( //
construct<OmpPreferenceSelector>("FR" >> parenthesized(indirect(expr))) ||
construct<OmpPreferenceSelector>(
"ATTR" >> parenthesized(nonemptyList(indirect(expr)))))
TYPE_PARSER( //
construct<OmpPreferenceSpecification>(
braced(nonemptyList(Parser<OmpPreferenceSelector>()))) ||
construct<OmpPreferenceSpecification>(indirect(expr)))
TYPE_PARSER(construct<OmpPreferType>( //
"PREFER_TYPE" >>
parenthesized(nonemptyList(Parser<OmpPreferenceSpecification>{}))))
TYPE_PARSER(construct<OmpPrescriptiveness>(
"STRICT" >> pure(OmpPrescriptiveness::Value::Strict)))
@ -986,9 +993,9 @@ TYPE_PARSER(sourced(
construct<OmpIfClause::Modifier>(Parser<OmpDirectiveNameModifier>{})))
TYPE_PARSER(sourced(
construct<OmpInitClause::Modifier>(
construct<OmpInitClause::Modifier>(Parser<OmpInteropPreference>{})) ||
construct<OmpInitClause::Modifier>(Parser<OmpInteropType>{})))
// Try interop-type first, since prefer-type can take arbitrary strings.
construct<OmpInitClause::Modifier>(Parser<OmpInteropType>{}) ||
construct<OmpInitClause::Modifier>(Parser<OmpPreferType>{})))
TYPE_PARSER(sourced(construct<OmpInReductionClause::Modifier>(
Parser<OmpReductionIdentifier>{})))
@ -1487,8 +1494,8 @@ TYPE_PARSER( //
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
"INDIRECT" >> construct<OmpClause>(construct<OmpClause::Indirect>(
maybe(parenthesized(scalarLogicalExpr)))) ||
"INIT" >> construct<OmpClause>(construct<OmpClause::Init>(
parenthesized(Parser<OmpInitClause>{}))) ||
"INIT"_id >> construct<OmpClause>(construct<OmpClause::Init>(
parenthesized(Parser<OmpInitClause>{}))) ||
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
parenthesized(Parser<OmpObjectList>{}))) ||
"INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(

View File

@ -2260,28 +2260,47 @@ public:
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpInteropPreference &x) { Walk(x.v, ","); }
void Unparse(const OmpPreferenceSelector &x) {
common::visit( //
common::visitors{
[&](const OmpPreferenceSelector::ForeignRuntimeIdentifier &s) {
Word("FR");
Put("(");
Walk(s);
Put(")");
},
[&](const OmpPreferenceSelector::Extensions &s) {
Word("ATTR");
Put("(");
Walk(s, ", ");
Put(")");
},
},
x.u);
}
void Unparse(const OmpPreferenceSpecification &x) {
common::visit( //
common::visitors{
[&](const std::list<OmpPreferenceSelector> &s) {
Put("{");
Walk(s, ", ");
Put("}");
},
[&](const OmpPreferenceSelector::ForeignRuntimeIdentifier &s) {
Walk(s);
},
},
x.u);
}
void Unparse(const OmpPreferType &x) {
Word("PREFER_TYPE");
Put("(");
Walk(x.v, ", ");
Put(")");
}
void Unparse(const OmpInitClause &x) {
using Modifier = OmpInitClause::Modifier;
auto &modifiers{std::get<std::optional<std::list<Modifier>>>(x.t)};
bool isTypeStart{true};
for (const Modifier &m : *modifiers) {
if (auto *interopPreferenceMod{
std::get_if<parser::OmpInteropPreference>(&m.u)}) {
Put("PREFER_TYPE(");
Walk(*interopPreferenceMod);
Put("),");
} else if (auto *interopTypeMod{
std::get_if<parser::OmpInteropType>(&m.u)}) {
if (isTypeStart) {
isTypeStart = false;
} else {
Put(",");
}
Walk(*interopTypeMod);
}
}
Put(": ");
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObject>(x.t));
}
void Unparse(const OmpMapClause &x) {
@ -2578,15 +2597,8 @@ public:
}
void Unparse(const OpenMPInteropConstruct &x) {
BeginOpenMP();
Word("!$OMP INTEROP");
auto flags{std::get<OmpDirectiveSpecification::Flags>(x.v.t)};
if (flags.test(OmpDirectiveSpecification::Flag::DeprecatedSyntax)) {
Walk("(", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
} else {
Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
Walk(" (", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
}
Word("!$OMP ");
Walk(x.v);
Put("\n");
EndOpenMP();
}

View File

@ -371,22 +371,6 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpFallbackModifier>() {
return desc;
}
template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpInteropPreference>() {
static const OmpModifierDescriptor desc{
/*name=*/"interop-preference",
/*props=*/
{
{52, {OmpProperty::Unique}},
},
/*clauses=*/
{
{52, {Clause::OMPC_init}},
},
};
return desc;
}
template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpInteropType>() {
static const OmpModifierDescriptor desc{
@ -553,6 +537,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>() {
return desc;
}
template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPreferType>() {
static const OmpModifierDescriptor desc{
/*name=*/"prefer-type",
/*props=*/
{
{52, {OmpProperty::Unique}},
},
/*clauses=*/
{
{52, {Clause::OMPC_init}},
},
};
return desc;
}
template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {
static const OmpModifierDescriptor desc{

View File

@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
! RUN: %flang_fc1 -fdebug-unparse -fopenmp-version=52 %openmp_flags %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp-version=52 %openmp_flags %s | FileCheck --check-prefix="PARSE-TREE" %s
! RUN: %flang_fc1 -fdebug-unparse -fopenmp-version=60 %openmp_flags %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp-version=60 %openmp_flags %s | FileCheck --check-prefix="PARSE-TREE" %s
SUBROUTINE test_interop_01()
!$OMP INTEROP DEVICE(1)
@ -12,21 +12,12 @@ END SUBROUTINE test_interop_01
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE test_interop_01
!PARSE-TREE: | SubroutineStmt
!PARSE-TREE: | | Name = 'test_interop_01'
!PARSE-TREE: | SpecificationPart
!PARSE-TREE: | | ImplicitPart ->
!PARSE-TREE: | ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
!PARSE-TREE: | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '1'
!PARSE-TREE: | | | Flags = {}
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
!PARSE-TREE: | | | Format -> Star
!PARSE-TREE: | | | OutputItem -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | | string = 'pass'
!PARSE-TREE: | EndSubroutineStmt -> Name = 'test_interop_01'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Device -> OmpDeviceClause
!PARSE-TREE: | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '1'
!PARSE-TREE: | Flags = {}
SUBROUTINE test_interop_02()
USE omp_lib
@ -42,34 +33,15 @@ END SUBROUTINE test_interop_02
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE test_interop_02
!PARSE-TREE: | SubroutineStmt
!PARSE-TREE: | | Name = 'test_interop_02'
!PARSE-TREE: | SpecificationPart
!PARSE-TREE: | | UseStmt
!PARSE-TREE: | | | Name = 'omp_lib'
!PARSE-TREE: | | ImplicitPart ->
!PARSE-TREE: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr -> Designator -> DataRef -> Name = 'omp_interop_kind'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj1'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj2'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj3'
!PARSE-TREE: | ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | | | OmpClause -> Use -> OmpUseClause -> OmpObject -> Designator -> DataRef -> Name = 'obj1'
!PARSE-TREE: | | | OmpClause -> Destroy -> OmpDestroyClause -> OmpObject -> Designator -> DataRef -> Name = 'obj3'
!PARSE-TREE: | | | Flags = {}
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
!PARSE-TREE: | | | Format -> Star
!PARSE-TREE: | | | OutputItem -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | | string = 'pass'
!PARSE-TREE: | EndSubroutineStmt -> Name = 'test_interop_02'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | OmpClause -> Use -> OmpUseClause -> OmpObject -> Designator -> DataRef -> Name = 'obj1'
!PARSE-TREE: | OmpClause -> Destroy -> OmpDestroyClause -> OmpObject -> Designator -> DataRef -> Name = 'obj3'
!PARSE-TREE: | Flags = {}
SUBROUTINE test_interop_03()
USE omp_lib
@ -85,31 +57,16 @@ END SUBROUTINE test_interop_03
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE test_interop_03
!PARSE-TREE: | SubroutineStmt
!PARSE-TREE: | | Name = 'test_interop_03'
!PARSE-TREE: | SpecificationPart
!PARSE-TREE: | | UseStmt
!PARSE-TREE: | | | Name = 'omp_lib'
!PARSE-TREE: | | ImplicitPart ->
!PARSE-TREE: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr -> Designator -> DataRef -> Name = 'omp_interop_kind'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj'
!PARSE-TREE: | ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | | | OmpClause -> Depend -> OmpDependClause -> TaskDep
!PARSE-TREE: | | | | Modifier -> OmpTaskDependenceType -> Value = Inout
!PARSE-TREE: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | | | Flags = {}
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
!PARSE-TREE: | | | Format -> Star
!PARSE-TREE: | | | OutputItem -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | | string = 'pass'
!PARSE-TREE: | EndSubroutineStmt -> Name = 'test_interop_03'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | OmpClause -> Depend -> OmpDependClause -> TaskDep
!PARSE-TREE: | | Modifier -> OmpTaskDependenceType -> Value = Inout
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | Flags = {}
SUBROUTINE test_interop_04()
USE omp_lib
@ -123,48 +80,25 @@ END SUBROUTINE test_interop_04
!UNPARSE: USE :: omp_lib
!UNPARSE: INTEGER(KIND=8_4) obj
!UNPARSE: INTEGER, DIMENSION(1_4,10_4) :: arr
!UNPARSE: !$OMP INTEROP INIT(PREFER_TYPE("cuda"),TARGETSYNC,TARGET: obj) DEPEND(INOUT: &
!UNPARSE: !$OMP&arr) NOWAIT
!UNPARSE: !$OMP INTEROP INIT(PREFER_TYPE("cuda"), TARGETSYNC, TARGET: obj) DEPEND(INOUT: arr) &
!UNPARSE: !$OMP&NOWAIT
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE test_interop_04
!PARSE-TREE: | SubroutineStmt
!PARSE-TREE: | | Name = 'test_interop_04'
!PARSE-TREE: | SpecificationPart
!PARSE-TREE: | | UseStmt
!PARSE-TREE: | | | Name = 'omp_lib'
!PARSE-TREE: | | ImplicitPart ->
!PARSE-TREE: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr -> Designator -> DataRef -> Name = 'omp_interop_kind'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj'
!PARSE-TREE: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | AttrSpec -> ArraySpec -> ExplicitShapeSpec
!PARSE-TREE: | | | | SpecificationExpr -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '1'
!PARSE-TREE: | | | ExplicitShapeSpec
!PARSE-TREE: | | | | SpecificationExpr -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '10'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'arr'
!PARSE-TREE: | ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | | | Modifier -> OmpInteropPreference -> OmpInteropRuntimeIdentifier -> CharLiteralConstant
!PARSE-TREE: | | | | | string = 'cuda'
!PARSE-TREE: | | | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | | | Modifier -> OmpInteropType -> Value = Target
!PARSE-TREE: | | | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | | | OmpClause -> Depend -> OmpDependClause -> TaskDep
!PARSE-TREE: | | | | Modifier -> OmpTaskDependenceType -> Value = Inout
!PARSE-TREE: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr'
!PARSE-TREE: | | | OmpClause -> Nowait
!PARSE-TREE: | | | Flags = {}
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
!PARSE-TREE: | | | Format -> Star
!PARSE-TREE: | | | OutputItem -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | | string = 'pass'
!PARSE-TREE: | EndSubroutineStmt -> Name = 'test_interop_04'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | Modifier -> OmpPreferType -> OmpPreferenceSpecification -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | string = 'cuda'
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = Target
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | OmpClause -> Depend -> OmpDependClause -> TaskDep
!PARSE-TREE: | | Modifier -> OmpTaskDependenceType -> Value = Inout
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr'
!PARSE-TREE: | OmpClause -> Nowait
!PARSE-TREE: | Flags = {}
SUBROUTINE test_interop_05()
USE omp_lib
@ -176,34 +110,45 @@ END SUBROUTINE test_interop_05
!UNPARSE: SUBROUTINE test_interop_05
!UNPARSE: USE :: omp_lib
!UNPARSE: INTEGER(KIND=8_4) obj
!UNPARSE: !$OMP INTEROP INIT(PREFER_TYPE(4_4),TARGETSYNC: obj) DEVICE(DEVICE_NUM: 0_4)
!UNPARSE: !$OMP INTEROP INIT(PREFER_TYPE(4_4), TARGETSYNC: obj) DEVICE(DEVICE_NUM: 0_4)
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE test_interop_05
!PARSE-TREE: | SubroutineStmt
!PARSE-TREE: | | Name = 'test_interop_05'
!PARSE-TREE: | SpecificationPart
!PARSE-TREE: | | UseStmt
!PARSE-TREE: | | | Name = 'omp_lib'
!PARSE-TREE: | | ImplicitPart ->
!PARSE-TREE: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr -> Designator -> DataRef -> Name = 'omp_interop_kind'
!PARSE-TREE: | | | EntityDecl
!PARSE-TREE: | | | | Name = 'obj'
!PARSE-TREE: | ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | | | Modifier -> OmpInteropPreference -> OmpInteropRuntimeIdentifier -> Scalar -> Integer -> Constant -> Expr -> Designator -> DataRef -> Name = 'omp_ifr_sycl'
!PARSE-TREE: | | | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | | | OmpClause -> Device -> OmpDeviceClause
!PARSE-TREE: | | | | Modifier -> OmpDeviceModifier -> Value = Device_Num
!PARSE-TREE: | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '0'
!PARSE-TREE: | | | Flags = {}
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
!PARSE-TREE: | | | Format -> Star
!PARSE-TREE: | | | OutputItem -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | | string = 'pass'
!PARSE-TREE: | EndSubroutineStmt -> Name = 'test_interop_05'
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | Modifier -> OmpPreferType -> OmpPreferenceSpecification -> Expr -> Designator -> DataRef -> Name = 'omp_ifr_sycl'
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | OmpClause -> Device -> OmpDeviceClause
!PARSE-TREE: | | Modifier -> OmpDeviceModifier -> Value = Device_Num
!PARSE-TREE: | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '0'
!PARSE-TREE: | Flags = {}
SUBROUTINE test_interop_06()
USE omp_lib
INTEGER(KIND=OMP_INTEROP_KIND) :: obj
!$OMP INTEROP INIT(PREFER_TYPE({FR("some_runtime"), ATTR("ext1", "ext2")}), TARGETSYNC: obj)
PRINT *, 'pass'
END
!UNPARSE: SUBROUTINE test_interop_06
!UNPARSE: USE :: omp_lib
!UNPARSE: INTEGER(KIND=8_4) obj
!UNPARSE: !$OMP INTEROP INIT(PREFER_TYPE({FR("some_runtime"), ATTR("ext1", "ext2")}), TARGETSYNC: obj)
!UNPARSE: PRINT *, "pass"
!UNPARSE: END SUBROUTINE
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPInteropConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = interop
!PARSE-TREE: | OmpClauseList -> OmpClause -> Init -> OmpInitClause
!PARSE-TREE: | | Modifier -> OmpPreferType -> OmpPreferenceSpecification -> OmpPreferenceSelector -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | string = 'some_runtime'
!PARSE-TREE: | | OmpPreferenceSelector -> Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | string = 'ext1'
!PARSE-TREE: | | Expr -> LiteralConstant -> CharLiteralConstant
!PARSE-TREE: | | | string = 'ext2'
!PARSE-TREE: | | Modifier -> OmpInteropType -> Value = TargetSync
!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'obj'
!PARSE-TREE: | Flags = {}