summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp57
1 files changed, 55 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 7a924b4ce2b..96cf37912f2 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -65,6 +65,7 @@ static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
static const unsigned F[][3] = {
{ OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
{ OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
+ { OMPD_declare, OMPD_simd, OMPD_declare_simd },
{ OMPD_target, OMPD_data, OMPD_target_data },
{ OMPD_target, OMPD_enter, OMPD_target_enter },
{ OMPD_target, OMPD_exit, OMPD_target_exit },
@@ -332,8 +333,14 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
/// annot_pragma_openmp 'declare' 'reduction' [...]
/// annot_pragma_openmp_end
///
-Parser::DeclGroupPtrTy
-Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
+/// declare-simd-directive:
+/// annot_pragma_openmp 'declare simd' {<clause> [,]}
+/// annot_pragma_openmp_end
+/// <function declaration/definition>
+///
+Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
+ AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
+ DeclSpec::TST TagType, Decl *Tag) {
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
@@ -373,6 +380,47 @@ Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
return Res;
}
break;
+ case OMPD_declare_simd: {
+ // The syntax is:
+ // { #pragma omp declare simd }
+ // <function-declaration-or-definition>
+ //
+
+ ConsumeToken();
+ // The last seen token is annot_pragma_openmp_end - need to check for
+ // extra tokens.
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(OMPD_declare_simd);
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ }
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeToken();
+
+ DeclGroupPtrTy Ptr;
+ if (Tok.is(tok::annot_pragma_openmp)) {
+ Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
+ } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
+ // Here we expect to see some function declaration.
+ if (AS == AS_none) {
+ assert(TagType == DeclSpec::TST_unspecified);
+ MaybeParseCXX11Attributes(Attrs);
+ MaybeParseMicrosoftAttributes(Attrs);
+ ParsingDeclSpec PDS(*this);
+ Ptr = ParseExternalDeclaration(Attrs, &PDS);
+ } else {
+ Ptr =
+ ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
+ }
+ }
+ if (!Ptr) {
+ Diag(Loc, diag::err_omp_decl_in_declare_simd);
+ return DeclGroupPtrTy();
+ }
+
+ return Actions.ActOnOpenMPDeclareSimdDirective(Ptr, Loc);
+ }
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
break;
@@ -627,6 +675,11 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
OMPDirectiveScope.Exit();
break;
}
+ case OMPD_declare_simd:
+ Diag(Tok, diag::err_omp_unexpected_directive)
+ << getOpenMPDirectiveName(DKind);
+ SkipUntil(tok::annot_pragma_openmp_end);
+ break;
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
SkipUntil(tok::annot_pragma_openmp_end);
OpenPOWER on IntegriCloud