From 3201ad61aa8da4cec3e33e9d2c407082f574266c Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 3 Oct 2017 20:00:00 +0000 Subject: [PATCH] [OPENMP] Allow use of declare target directive inside struct declaration. Patch allows using of the `#pragma omp declare target`| `#pragma omp end declare target` directives inside the structures if we need to mark as declare target only some static members. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314833 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Parse/ParseOpenMP.cpp | 14 +++++++++--- lib/Sema/SemaOpenMP.cpp | 6 +++++- test/OpenMP/declare_target_ast_print.cpp | 27 ++++++++++++++++++++++++ test/OpenMP/declare_target_messages.cpp | 4 ++-- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 669e9aff80..e1685f6a9d 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -760,9 +760,17 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( DKind = ParseOpenMPDirectiveKind(*this); while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target && Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { - ParsedAttributesWithRange attrs(AttrFactory); - MaybeParseCXX11Attributes(attrs); - ParseExternalDeclaration(attrs); + DeclGroupPtrTy Ptr; + // Here we expect to see some function declaration. + if (AS == AS_none) { + assert(TagType == DeclSpec::TST_unspecified); + MaybeParseCXX11Attributes(Attrs); + ParsingDeclSpec PDS(*this); + Ptr = ParseExternalDeclaration(Attrs, &PDS); + } else { + Ptr = + ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); + } if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { TentativeParsingAction TPA(*this); ConsumeAnnotationToken(); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 8bded5854a..81fea56033 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -11914,7 +11914,11 @@ bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { DeclContext *CurLexicalContext = getCurLexicalContext(); if (!CurLexicalContext->isFileContext() && !CurLexicalContext->isExternCContext() && - !CurLexicalContext->isExternCXXContext()) { + !CurLexicalContext->isExternCXXContext() && + !isa(CurLexicalContext) && + !isa(CurLexicalContext) && + !isa(CurLexicalContext) && + !isa(CurLexicalContext)) { Diag(Loc, diag::err_omp_region_not_file_context); return false; } diff --git a/test/OpenMP/declare_target_ast_print.cpp b/test/OpenMP/declare_target_ast_print.cpp index 591844b794..55f73cbc4e 100644 --- a/test/OpenMP/declare_target_ast_print.cpp +++ b/test/OpenMP/declare_target_ast_print.cpp @@ -124,6 +124,33 @@ void f3() { // CHECK: void f3() // CHECK: #pragma omp end declare target +struct SSSt { +#pragma omp declare target + static int a; + int b; +#pragma omp end declare target +}; + +// CHECK: struct SSSt { +// CHECK: #pragma omp declare target +// CHECK: static int a; +// CHECK: #pragma omp end declare target +// CHECK: int b; + +template +struct SSSTt { +#pragma omp declare target + static T a; + int b; +#pragma omp end declare target +}; + +// CHECK: template struct SSSTt { +// CHECK: #pragma omp declare target +// CHECK: static T a; +// CHECK: #pragma omp end declare target +// CHECK: int b; + int main (int argc, char **argv) { foo(); foo_c(); diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp index 5180dd762b..bbffc0eeeb 100644 --- a/test/OpenMP/declare_target_messages.cpp +++ b/test/OpenMP/declare_target_messages.cpp @@ -73,9 +73,9 @@ int C::method() { } struct S { -#pragma omp declare target // expected-error {{directive must be at file or namespace scope}} +#pragma omp declare target int v; -#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +#pragma omp end declare target }; int main (int argc, char **argv) { -- 2.40.0