From: Alexey Bataev Date: Tue, 3 Oct 2017 20:00:00 +0000 (+0000) Subject: [OPENMP] Allow use of declare target directive inside struct X-Git-Tag: llvmorg-6.0.0-rc1~6599 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=502ec49793faad5587f8c855a5f8914837594987;p=platform%2Fupstream%2Fllvm.git [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. llvm-svn: 314833 --- diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 669e9aff8021..e1685f6a9dbf 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/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/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 8bded5854aa3..81fea56033c9 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/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/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index 591844b79498..55f73cbc4e97 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/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/clang/test/OpenMP/declare_target_messages.cpp b/clang/test/OpenMP/declare_target_messages.cpp index 5180dd762bdb..bbffc0eeeb2a 100644 --- a/clang/test/OpenMP/declare_target_messages.cpp +++ b/clang/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) {