diff options
| author | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-06 11:38:59 +0000 |
|---|---|---|
| committer | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-06 11:38:59 +0000 |
| commit | 0b0da296e6de09610621467279a99eb290522a88 (patch) | |
| tree | 1658d323a4f2382dfdfdb387db998bfde5095e9d /clang/lib/Parse | |
| parent | b1f7d4d79cbc720bba2c0f82cfe0a0e0c6077896 (diff) | |
| download | bcm5719-llvm-0b0da296e6de09610621467279a99eb290522a88.tar.gz bcm5719-llvm-0b0da296e6de09610621467279a99eb290522a88.zip | |
[OPENMP] Parsing and Sema support for 'omp declare target' directive
Add parsing, sema analysis for 'declare target' construct for OpenMP 4.0
(4.5 support will be added in separate patch).
The declare target directive specifies that variables, functions (C, C++
and Fortran), and subroutines (Fortran) are mapped to a device. The declare
target directive is a declarative directive. In Clang declare target is
implemented as implicit attribute for the declaration.
The syntax of the declare target directive is as follows:
#pragma omp declare target
declarations-definition-seq
#pragma omp end declare target
Based on patch from Michael Wong http://reviews.llvm.org/D15321
llvm-svn: 265530
Diffstat (limited to 'clang/lib/Parse')
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index dcff1595611..a280bb9e267 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -31,6 +31,8 @@ enum OpenMPDirectiveKindEx { OMPD_cancellation = OMPD_unknown + 1, OMPD_data, OMPD_declare, + OMPD_end, + OMPD_end_declare, OMPD_enter, OMPD_exit, OMPD_point, @@ -51,6 +53,7 @@ static unsigned getOpenMPDirectiveKindEx(StringRef S) { .Case("cancellation", OMPD_cancellation) .Case("data", OMPD_data) .Case("declare", OMPD_declare) + .Case("end", OMPD_end) .Case("enter", OMPD_enter) .Case("exit", OMPD_exit) .Case("point", OMPD_point) @@ -66,6 +69,9 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { { OMPD_cancellation, OMPD_point, OMPD_cancellation_point }, { OMPD_declare, OMPD_reduction, OMPD_declare_reduction }, { OMPD_declare, OMPD_simd, OMPD_declare_simd }, + { OMPD_declare, OMPD_target, OMPD_declare_target }, + { OMPD_end, OMPD_declare, OMPD_end_declare }, + { OMPD_end_declare, OMPD_target, OMPD_end_declare_target }, { OMPD_target, OMPD_data, OMPD_target_data }, { OMPD_target, OMPD_enter, OMPD_target_enter }, { OMPD_target, OMPD_exit, OMPD_target_exit }, @@ -456,6 +462,53 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, BS, SourceRange(Loc, EndLoc)); } + case OMPD_declare_target: { + SourceLocation DTLoc = ConsumeAnyToken(); + if (Tok.isNot(tok::annot_pragma_openmp_end)) { + Diag(Tok, diag::warn_omp_extra_tokens_at_eol) + << getOpenMPDirectiveName(OMPD_declare_target); + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + } + // Skip the last annot_pragma_openmp_end. + ConsumeAnyToken(); + + if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc)) + return DeclGroupPtrTy(); + + 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); + MaybeParseMicrosoftAttributes(attrs); + ParseExternalDeclaration(attrs); + if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { + TentativeParsingAction TPA(*this); + ConsumeToken(); + DKind = ParseOpenMPDirectiveKind(*this); + if (DKind != OMPD_end_declare_target) + TPA.Revert(); + else + TPA.Commit(); + } + } + + if (DKind == OMPD_end_declare_target) { + ConsumeAnyToken(); + if (Tok.isNot(tok::annot_pragma_openmp_end)) { + Diag(Tok, diag::warn_omp_extra_tokens_at_eol) + << getOpenMPDirectiveName(OMPD_end_declare_target); + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + } + // Skip the last annot_pragma_openmp_end. + ConsumeAnyToken(); + } else { + Diag(Tok, diag::err_expected_end_declare_target); + Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'"; + } + Actions.ActOnFinishOpenMPDeclareTargetDirective(); + return DeclGroupPtrTy(); + } case OMPD_unknown: Diag(Tok, diag::err_omp_unknown_directive); break; @@ -491,6 +544,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_taskloop: case OMPD_taskloop_simd: case OMPD_distribute: + case OMPD_end_declare_target: Diag(Tok, diag::err_omp_unexpected_directive) << getOpenMPDirectiveName(DKind); break; @@ -711,6 +765,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( break; } case OMPD_declare_simd: + case OMPD_declare_target: + case OMPD_end_declare_target: Diag(Tok, diag::err_omp_unexpected_directive) << getOpenMPDirectiveName(DKind); SkipUntil(tok::annot_pragma_openmp_end); |

