diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index cb775ba0d9287..e860893b933ca 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -103,6 +103,37 @@ enum class OpenACCClauseKind { Copy, /// 'use_device' clause, allowed on 'host_data' construct. UseDevice, + /// 'attach' clause, allowed on Compute and Combined constructs, plus 'data' + /// and 'enter data'. + Attach, + /// 'delete' clause, allowed on the 'exit data' construct. + Delete, + /// 'detach' clause, allowed on the 'exit data' construct. + Detach, + /// 'device' clause, allowed on the 'update' construct. + Device, + /// 'deviceptr' clause, allowed on Compute and Combined Constructs, plus + /// 'data' and 'declare'. + DevicePtr, + /// 'device_resident' clause, allowed on the 'declare' construct. + DeviceResident, + /// 'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop', + /// and 'serial loop' constructs. + FirstPrivate, + /// 'host' clause, allowed on 'update' construct. + Host, + /// 'link' clause, allowed on 'declare' construct. + Link, + /// 'no_create' clause, allowed on allowed on Compute and Combined constructs, + /// plus 'data'. + NoCreate, + /// 'present' clause, allowed on Compute and Combined constructs, plus 'data' + /// and 'declare'. + Present, + /// 'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel + /// loop', and 'serial loop' constructs. + Private, + /// Represents an invalid clause, for the purposes of parsing. Invalid, }; diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index c94f48d3ec04f..83378a094492b 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -87,16 +87,29 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) { if (!Tok.is(tok::identifier)) return OpenACCClauseKind::Invalid; + // TODO: ERICH: add new clauses here. return llvm::StringSwitch( Tok.getIdentifierInfo()->getName()) + .Case("attach",OpenACCClauseKind::Attach) .Case("auto", OpenACCClauseKind::Auto) .Case("copy", OpenACCClauseKind::Copy) .Case("default", OpenACCClauseKind::Default) + .Case("delete", OpenACCClauseKind::Delete) + .Case("detach", OpenACCClauseKind::Detach) + .Case("device", OpenACCClauseKind::Device) + .Case("device_resident", OpenACCClauseKind::DeviceResident) + .Case("deviceptr", OpenACCClauseKind::DevicePtr) .Case("finalize", OpenACCClauseKind::Finalize) + .Case("firstprivate", OpenACCClauseKind::FirstPrivate) + .Case("host", OpenACCClauseKind::Host) .Case("if", OpenACCClauseKind::If) .Case("if_present", OpenACCClauseKind::IfPresent) .Case("independent", OpenACCClauseKind::Independent) + .Case("link", OpenACCClauseKind::Link) + .Case("no_create", OpenACCClauseKind::NoCreate) .Case("nohost", OpenACCClauseKind::NoHost) + .Case("present", OpenACCClauseKind::Present) + .Case("private", OpenACCClauseKind::Private) .Case("self", OpenACCClauseKind::Self) .Case("seq", OpenACCClauseKind::Seq) .Case("use_device", OpenACCClauseKind::UseDevice) @@ -331,14 +344,55 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { return DirKind; } +enum ClauseParensKind { + None, + Optional, + Required +}; + +ClauseParensKind getClauseParensKind(OpenACCClauseKind Kind) { + switch (Kind) { + case OpenACCClauseKind::Self: + return ClauseParensKind::Optional; + + case OpenACCClauseKind::Default: + case OpenACCClauseKind::If: + case OpenACCClauseKind::Copy: + case OpenACCClauseKind::UseDevice: + case OpenACCClauseKind::NoCreate: + case OpenACCClauseKind::Present: + case OpenACCClauseKind::DevicePtr: + case OpenACCClauseKind::Attach: + case OpenACCClauseKind::Detach: + case OpenACCClauseKind::Private: + case OpenACCClauseKind::FirstPrivate: + case OpenACCClauseKind::Delete: + case OpenACCClauseKind::DeviceResident: + case OpenACCClauseKind::Device: + case OpenACCClauseKind::Link: + case OpenACCClauseKind::Host: + return ClauseParensKind::Required; + + case OpenACCClauseKind::Auto: + case OpenACCClauseKind::Finalize: + case OpenACCClauseKind::IfPresent: + case OpenACCClauseKind::Independent: + case OpenACCClauseKind::Invalid: + case OpenACCClauseKind::NoHost: + case OpenACCClauseKind::Seq: + case OpenACCClauseKind::Worker: + case OpenACCClauseKind::Vector: + return ClauseParensKind::None; + } + llvm_unreachable("Unhandled clause kind"); +} + bool ClauseHasOptionalParens(OpenACCClauseKind Kind) { - return Kind == OpenACCClauseKind::Self; + return getClauseParensKind(Kind) == ClauseParensKind::Optional; } bool ClauseHasRequiredParens(OpenACCClauseKind Kind) { - return Kind == OpenACCClauseKind::Default || Kind == OpenACCClauseKind::If || - Kind == OpenACCClauseKind::Copy || - Kind == OpenACCClauseKind::UseDevice; + return getClauseParensKind(Kind) == ClauseParensKind::Required; } ExprResult ParseOpenACCConditionalExpr(Parser &P) { @@ -463,8 +517,20 @@ bool Parser::ParseOpenACCClauseParams(OpenACCClauseKind Kind) { return true; break; } - case OpenACCClauseKind::UseDevice: + case OpenACCClauseKind::Attach: case OpenACCClauseKind::Copy: + case OpenACCClauseKind::Delete: + case OpenACCClauseKind::Detach: + case OpenACCClauseKind::Device: + case OpenACCClauseKind::DeviceResident: + case OpenACCClauseKind::DevicePtr: + case OpenACCClauseKind::FirstPrivate: + case OpenACCClauseKind::Host: + case OpenACCClauseKind::Link: + case OpenACCClauseKind::NoCreate: + case OpenACCClauseKind::Present: + case OpenACCClauseKind::Private: + case OpenACCClauseKind::UseDevice: if (ParseOpenACCClauseVarList(Kind)) return true; break; diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index 623136f76d000..053d007839dc7 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -405,6 +405,98 @@ void VarListClauses() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial use_device(s.array[s.value : 5]), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial no_create(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial no_create(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial present(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial present(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial deviceptr(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial deviceptr(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial attach(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial attach(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial detach(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial detach(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial private(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial private(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial firstprivate(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial firstprivate(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial delete(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial delete(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial use_device(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial device_resident(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial device_resident(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial link(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial link(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial host(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial host(s.array[s.value : 5], s.value), seq + + // expected-error@+2{{expected ','}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial device(s.array[s.value] s.array[s.value :5] ), seq + + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc serial device(s.array[s.value : 5], s.value), seq + } // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}