diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9945b225587a..3ff595c8e9ca 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8783,8 +8783,6 @@ def warn_omp_linear_step_zero : Warning< def warn_omp_alignment_not_power_of_two : Warning< "aligned clause will be ignored because the requested alignment is not a power of 2">, InGroup; -def err_omp_enclosed_declare_target : Error< - "declare target region may not be enclosed within another declare target region">; def err_omp_invalid_target_decl : Error< "%0 used in declare target directive is not a variable or a function name">; def err_omp_declare_target_multiple : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 04ba15edb392..9556fdab3a76 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8601,8 +8601,8 @@ public: // private: void *VarDataSharingAttributesStack; - /// Set to true inside '#pragma omp declare target' region. - bool IsInOpenMPDeclareTargetContext = false; + /// Number of nested '#pragma omp declare target' directives. + unsigned DeclareTargetNestingLevel = 0; /// Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); @@ -8736,7 +8736,7 @@ public: SourceLocation IdLoc = SourceLocation()); /// Return true inside OpenMP declare target region. bool isInOpenMPDeclareTargetContext() const { - return IsInOpenMPDeclareTargetContext; + return DeclareTargetNestingLevel > 0; } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index b3c7e3a63d09..4da357bbbc77 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -775,8 +775,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( llvm::SmallVector Decls; DKind = parseOpenMPDirectiveKind(*this); - while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target && - Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { + while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) && + Tok.isNot(tok::r_brace)) { DeclGroupPtrTy Ptr; // Here we expect to see some function declaration. if (AS == AS_none) { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 215b4bf10902..3664f9a5fd4b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -12960,19 +12960,14 @@ bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { Diag(Loc, diag::err_omp_region_not_file_context); return false; } - if (IsInOpenMPDeclareTargetContext) { - Diag(Loc, diag::err_omp_enclosed_declare_target); - return false; - } - - IsInOpenMPDeclareTargetContext = true; + ++DeclareTargetNestingLevel; return true; } void Sema::ActOnFinishOpenMPDeclareTargetDirective() { - assert(IsInOpenMPDeclareTargetContext && + assert(DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); - IsInOpenMPDeclareTargetContext = false; + --DeclareTargetNestingLevel; } void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, diff --git a/clang/test/OpenMP/Inputs/declare_target_include.h b/clang/test/OpenMP/Inputs/declare_target_include.h new file mode 100644 index 000000000000..b74cd00819db --- /dev/null +++ b/clang/test/OpenMP/Inputs/declare_target_include.h @@ -0,0 +1,3 @@ +#pragma omp declare target + void zyx(); +#pragma omp end declare target diff --git a/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index 921b96a4462f..613926d5f614 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/test/OpenMP/declare_target_ast_print.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -I %S/Inputs -verify %s -ast-print | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -I %S/Inputs -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -I %S/Inputs -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -191,6 +191,32 @@ int baz() { return 1; } // CHECK: } // CHECK: #pragma omp end declare target +#pragma omp declare target + #include "declare_target_include.h" + void xyz(); +#pragma omp end declare target + +// CHECK: #pragma omp declare target +// CHECK: void zyx(); +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: void xyz(); +// CHECK: #pragma omp end declare target + +#pragma omp declare target + #pragma omp declare target + void abc(); + #pragma omp end declare target + void cba(); +#pragma omp end declare target + +// CHECK: #pragma omp declare target +// CHECK: void abc(); +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: void cba(); +// CHECK: #pragma omp end declare target + 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 c8e73f6efbd7..6fe9b1aefc45 100644 --- a/clang/test/OpenMP/declare_target_messages.cpp +++ b/clang/test/OpenMP/declare_target_messages.cpp @@ -59,8 +59,19 @@ void t2() { } } +#pragma omp declare target + void abc(); +#pragma omp end declare target +void cba(); +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} -#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}} +#pragma omp declare target + #pragma omp declare target + void def(); + #pragma omp end declare target + void fed(); + +#pragma omp declare target #pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}} extern int b; int g; @@ -100,9 +111,12 @@ void foo(int p) { f(); c(); } -#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} +#pragma omp declare target void foo1() {} #pragma omp end declare target + +#pragma omp end declare target +#pragma omp end declare target #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} int C::method() {