[PATCH] D10599: [OPENMP 4.0] Initial support for '#pragma omp declare simd' directive.

Aaron Ballman aaron.ballman at gmail.com
Wed Jul 8 13:55:04 PDT 2015


LGTM with one question below. I would wait for review from Richard or
Hal before committing.

> Index: lib/Parse/ParseOpenMP.cpp
> ===================================================================
> --- lib/Parse/ParseOpenMP.cpp
> +++ lib/Parse/ParseOpenMP.cpp
> @@ -30,6 +30,7 @@
>    // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
>    // TODO: add other combined directives in topological order.
>    const OpenMPDirectiveKind F[][3] = {
> +      {OMPD_unknown /*declare*/, OMPD_simd, OMPD_declare_simd},
>        {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/,
>         OMPD_cancellation_point},
>        {OMPD_for, OMPD_simd, OMPD_for_simd},
> @@ -43,25 +44,25 @@
>            : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
>    bool TokenMatched = false;
>    for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
> -    if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
> +    if (!Tok.isAnnotation() && DKind == OMPD_unknown)
>        TokenMatched =
> -          (i == 0) &&
> -          !P.getPreprocessor().getSpelling(Tok).compare("cancellation");
> -    } else {
> +          ((i == 0) &&
> +           !P.getPreprocessor().getSpelling(Tok).compare("declare")) ||
> +          ((i == 1) &&
> +           !P.getPreprocessor().getSpelling(Tok).compare("cancellation"));
> +    else
>        TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
> -    }
>      if (TokenMatched) {
>        Tok = P.getPreprocessor().LookAhead(0);
>        auto SDKind =
>            Tok.isAnnotation()
>                ? OMPD_unknown
>                : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
> -      if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
> +      if (!Tok.isAnnotation() && SDKind == OMPD_unknown)
>          TokenMatched =
> -            (i == 0) && !P.getPreprocessor().getSpelling(Tok).compare("point");
> -      } else {
> +            (i == 1) && !P.getPreprocessor().getSpelling(Tok).compare("point");
> +      else
>          TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
> -      }
>        if (TokenMatched) {
>          P.ConsumeToken();
>          DKind = F[i][2];
> @@ -75,14 +76,25 @@
>  ///
>  ///       threadprivate-directive:
>  ///         annot_pragma_openmp 'threadprivate' simple-variable-list
> +///         annot_pragma_omp_end
>  ///
> -Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
> +///       declare-simd-directive:
> +///         annot_pragma_openmp 'declare simd' {<clause> [,]}
> +///         annot_pragma_omp_end
> +///         <function declaration/definition>
> +///
> +Parser::DeclGroupPtrTy
> +Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(bool IsInTagDecl,
> +                                                   unsigned Level) {
>    assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
>    ParenBraceBracketBalancer BalancerRAIIObj(*this);
>
> +  auto AnnotationVal = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
>    SourceLocation Loc = ConsumeToken();
>    SmallVector<Expr *, 5> Identifiers;
> -  auto DKind = ParseOpenMPDirectiveKind(*this);
> +  OpenMPDirectiveKind DKind =
> +      (AnnotationVal == 0) ? ParseOpenMPDirectiveKind(*this)
> +                           : static_cast<OpenMPDirectiveKind>(AnnotationVal);
>
>    switch (DKind) {
>    case OMPD_threadprivate:
> @@ -100,6 +112,86 @@
>        return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
>      }
>      break;
> +  case OMPD_declare_simd: {
> +    // The syntax is:
> +    // { #pragma omp declare simd }
> +    // <function-declaration-or-definition>
> +    //
> +    if (AnnotationVal == 0)
> +      // Skip 'simd' if it was restored from cached tokens.
> +      ConsumeToken();
> +    if (IsInTagDecl) {
> +      LateParseOpenMPDeclarativeDirectiveWithTemplateFunction(
> +          /*DKind=*/OMPD_declare_simd, Loc);
> +      return DeclGroupPtrTy();
> +    }
> +
> +    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
> +        FirstClauses(OMPC_unknown + 1);
> +    SmallVector<OMPClause *, 4> Clauses;
> +    SmallVector<Token, 8> CachedPragmas;
> +
> +    while (Tok.isNot(tok::annot_pragma_openmp_end) && Tok.isNot(tok::eof)) {
> +      CachedPragmas.push_back(Tok);
> +      ConsumeAnyToken();
> +    }
> +    CachedPragmas.push_back(Tok);
> +    if (Tok.isNot(tok::eof))
> +      ConsumeAnyToken();
> +
> +    DeclGroupPtrTy Ptr;
> +    if (Tok.is(tok::annot_pragma_openmp)) {
> +      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(IsInTagDecl, Level + 1);
> +    } else {
> +      // Here we expect to see some function declaration.
> +      ParsedAttributesWithRange Attrs(AttrFactory);
> +      MaybeParseCXX11Attributes(Attrs);
> +      MaybeParseMicrosoftAttributes(Attrs);
> +      ParsingDeclSpec PDS(*this);
> +      Ptr = ParseExternalDeclaration(Attrs, &PDS);
> +    }
> +    if (!Ptr || Ptr.get().isNull())
> +      return DeclGroupPtrTy();
> +    if (Ptr.get().isDeclGroup()) {
> +      Diag(Tok, diag::err_omp_single_decl_in_declare_simd);
> +      return DeclGroupPtrTy();

Would it make sense to return Ptr here instead so that further
diagnostics can be reported?

~Aaron

On Wed, Jul 8, 2015 at 12:35 AM, Alexey Bataev <a.bataev at hotmail.com> wrote:
>
>
> Update after review
>
>
> http://reviews.llvm.org/D10599
>
> Files:
>   include/clang/AST/ASTMutationListener.h
>   include/clang/Basic/Attr.td
>   include/clang/Basic/AttrDocs.td
>   include/clang/Basic/DiagnosticParseKinds.td
>   include/clang/Basic/DiagnosticSemaKinds.td
>   include/clang/Basic/OpenMPKinds.def
>   include/clang/Parse/Parser.h
>   include/clang/Sema/Sema.h
>   include/clang/Serialization/ASTWriter.h
>   lib/AST/DeclPrinter.cpp
>   lib/Basic/OpenMPKinds.cpp
>   lib/Frontend/MultiplexConsumer.cpp
>   lib/Parse/ParseDeclCXX.cpp
>   lib/Parse/ParseOpenMP.cpp
>   lib/Parse/Parser.cpp
>   lib/Sema/SemaOpenMP.cpp
>   lib/Serialization/ASTCommon.h
>   lib/Serialization/ASTReaderDecl.cpp
>   lib/Serialization/ASTWriter.cpp
>   test/OpenMP/declare_simd_ast_print.c
>   test/OpenMP/declare_simd_ast_print.cpp
>   test/OpenMP/declare_simd_messages.cpp
>



More information about the cfe-commits mailing list