Ok, good! Thanks for the review!

Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team

30.07.2014 19:25, Michael Wong пишет:
Ok, I understand, thanks. Then the code looks good.


On Wed, Jul 30, 2014 at 12:54 AM, Bataev, Alexey <[email protected] <mailto:[email protected]>> wrote:

    Mike, currently there is no analysis for internal structure of the
    expressions associated with the 'omp atomic' directive. I'll add
    the tests for all these combinations when the real analysis of the
    expressions is added to clang.

    Best regards,
    Alexey Bataev
    =============
    Software Engineer
    Intel Compiler Team

    30.07.2014 0:54, Michael Wong пишет:
    I reviewed this and the structure is again similar to the review for


        r212516 - [OPENMP] Parsing and sema analysis for 'omp
        parallel sections' directive.


    It seems good except


    The testing seems sparse. For OMP atomic (in 4.0 at least), we
    support:

    If clause is update or not present:
    x++;
    x--;
    ++x;
    --x;
    x binop= expr;
    x = x binop expr;
    x = expr binop x;


    Shouldn't we test all these combinations? If they are there
    already and I missed them, then I apologize.  Thanks.





    On Tue, Jul 22, 2014 at 6:10 AM, Alexey Bataev
    <[email protected] <mailto:[email protected]>> wrote:

        Author: abataev
        Date: Tue Jul 22 05:10:35 2014
        New Revision: 213639

        URL: http://llvm.org/viewvc/llvm-project?rev=213639&view=rev
        Log:
        [OPENMP] Initial parsing and sema analysis for 'atomic'
        directive.

        Added:
            cfe/trunk/test/OpenMP/atomic_ast_print.cpp   (with props)
            cfe/trunk/test/OpenMP/atomic_messages.cpp   (with props)
        Modified:
            cfe/trunk/include/clang-c/Index.h
        cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
        cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
            cfe/trunk/include/clang/AST/StmtOpenMP.h
        cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
        cfe/trunk/include/clang/Basic/OpenMPKinds.def
            cfe/trunk/include/clang/Basic/StmtNodes.td
            cfe/trunk/include/clang/Sema/Sema.h
        cfe/trunk/include/clang/Serialization/ASTBitCodes.h
            cfe/trunk/lib/AST/Stmt.cpp
            cfe/trunk/lib/AST/StmtPrinter.cpp
            cfe/trunk/lib/AST/StmtProfile.cpp
            cfe/trunk/lib/Basic/OpenMPKinds.cpp
            cfe/trunk/lib/CodeGen/CGStmt.cpp
            cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
            cfe/trunk/lib/CodeGen/CodeGenFunction.h
            cfe/trunk/lib/Parse/ParseOpenMP.cpp
            cfe/trunk/lib/Sema/SemaOpenMP.cpp
            cfe/trunk/lib/Sema/TreeTransform.h
        cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
        cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
        cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
            cfe/trunk/tools/libclang/CIndex.cpp
            cfe/trunk/tools/libclang/CXCursor.cpp

        Modified: cfe/trunk/include/clang-c/Index.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang-c/Index.h (original)
        +++ cfe/trunk/include/clang-c/Index.h Tue Jul 22 05:10:35 2014
        @@ -2190,14 +2190,18 @@ enum CXCursorKind {
           /** \brief OpenMP flush directive.
            */
           CXCursor_OMPFlushDirective             = 246,
        -
        +
           /** \brief OpenMP ordered directive.
            */
           CXCursor_OMPOrderedDirective           = 247,

        +  /** \brief OpenMP atomic directive.
        +   */
        +  CXCursor_OMPAtomicDirective            = 248,
        +
           /** \brief Windows Structured Exception Handling's leave
        statement.
            */
        -  CXCursor_SEHLeaveStmt                  = 248,
        +  CXCursor_SEHLeaveStmt                  = 249,

           CXCursor_LastStmt                      =
        CXCursor_SEHLeaveStmt,


        Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
        (original)
        +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Tue
        Jul 22 05:10:35 2014
        @@ -2329,6 +2329,9 @@ DEF_TRAVERSE_STMT(OMPFlushDirective,
         DEF_TRAVERSE_STMT(OMPOrderedDirective,
                           {
        TRY_TO(TraverseOMPExecutableDirective(S)); })

        +DEF_TRAVERSE_STMT(OMPAtomicDirective,
        +                  {
        TRY_TO(TraverseOMPExecutableDirective(S)); })
        +
         // OpenMP clauses.
         template <typename Derived>
         bool
        RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {

        Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
        +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jul
        22 05:10:35 2014
        @@ -2351,6 +2351,9 @@ DEF_TRAVERSE_STMT(OMPFlushDirective,
         DEF_TRAVERSE_STMT(OMPOrderedDirective,
                           {
        TRY_TO(TraverseOMPExecutableDirective(S)); })

        +DEF_TRAVERSE_STMT(OMPAtomicDirective,
        +                  {
        TRY_TO(TraverseOMPExecutableDirective(S)); })
        +
         // OpenMP clauses.
         template <typename Derived>
         bool
        RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {

        Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
        +++ cfe/trunk/include/clang/AST/StmtOpenMP.h Tue Jul 22
        05:10:35 2014
        @@ -1075,6 +1075,62 @@ public:
           }
         };

        +/// \brief This represents '#pragma omp atomic' directive.
        +///
        +/// \code
        +/// #pragma omp atomic capture
        +/// \endcode
        +/// In this example directive '#pragma omp atomic' has
        clause 'capture'.
        +///
        +class OMPAtomicDirective : public OMPExecutableDirective {
        +  friend class ASTStmtReader;
        +  /// \brief Build directive with the given start and end
        location.
        +  ///
        +  /// \param StartLoc Starting location of the directive kind.
        +  /// \param EndLoc Ending location of the directive.
        +  /// \param NumClauses Number of clauses.
        +  ///
        +  OMPAtomicDirective(SourceLocation StartLoc, SourceLocation
        EndLoc,
        +                     unsigned NumClauses)
        +      : OMPExecutableDirective(this,
        OMPAtomicDirectiveClass, OMPD_atomic,
        +                               StartLoc, EndLoc, NumClauses,
        1) {}
        +
        +  /// \brief Build an empty directive.
        +  ///
        +  /// \param NumClauses Number of clauses.
        +  ///
        +  explicit OMPAtomicDirective(unsigned NumClauses)
        +      : OMPExecutableDirective(this,
        OMPAtomicDirectiveClass, OMPD_atomic,
        + SourceLocation(), SourceLocation(), NumClauses,
        +                               1) {}
        +
        +public:
        +  /// \brief Creates directive with a list of \a Clauses.
        +  ///
        +  /// \param C AST context.
        +  /// \param StartLoc Starting location of the directive kind.
        +  /// \param EndLoc Ending Location of the directive.
        +  /// \param Clauses List of clauses.
        +  /// \param AssociatedStmt Statement, associated with the
        directive.
        +  ///
        +  static OMPAtomicDirective *
        +  Create(const ASTContext &C, SourceLocation StartLoc,
        SourceLocation EndLoc,
        +         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
        +
        +  /// \brief Creates an empty directive with the place for
        \a NumClauses
        +  /// clauses.
        +  ///
        +  /// \param C AST context.
        +  /// \param NumClauses Number of clauses.
        +  ///
        +  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
        + unsigned NumClauses, EmptyShell);
        +
        +  static bool classof(const Stmt *T) {
        +    return T->getStmtClass() == OMPAtomicDirectiveClass;
        +  }
        +};
        +
         } // end namespace clang

         #endif

        Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
        (original)
        +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue
        Jul 22 05:10:35 2014
        @@ -7127,6 +7127,8 @@ def err_omp_prohibited_region : Error<
           "; perhaps you forget to enclose 'omp %3' directive into a
        for or a parallel for region with 'ordered' clause?}2">;
         def err_omp_prohibited_region_simd : Error<
           "OpenMP constructs may not be nested inside a simd region">;
        +def err_omp_prohibited_region_atomic : Error<
        +  "OpenMP constructs may not be nested inside an atomic
        region">;
         def err_omp_prohibited_region_critical_same_name : Error<
           "cannot nest 'critical' regions having the same name %0">;
         def note_omp_previous_critical_region : Note<

        Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
        +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Jul 22
        05:10:35 2014
        @@ -45,6 +45,9 @@
         #ifndef OPENMP_TASK_CLAUSE
         #  define OPENMP_TASK_CLAUSE(Name)
         #endif
        +#ifndef OPENMP_ATOMIC_CLAUSE
        +#  define OPENMP_ATOMIC_CLAUSE(Name)
        +#endif
         #ifndef OPENMP_DEFAULT_KIND
         #  define OPENMP_DEFAULT_KIND(Name)
         #endif
        @@ -71,6 +74,7 @@ OPENMP_DIRECTIVE(barrier)
         OPENMP_DIRECTIVE(taskwait)
         OPENMP_DIRECTIVE(flush)
         OPENMP_DIRECTIVE(ordered)
        +OPENMP_DIRECTIVE(atomic)
         OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
         OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")

        @@ -206,6 +210,7 @@ OPENMP_TASK_CLAUSE(mergeable)
         #undef OPENMP_PARALLEL_FOR_CLAUSE
         #undef OPENMP_PARALLEL_SECTIONS_CLAUSE
         #undef OPENMP_TASK_CLAUSE
        +#undef OPENMP_ATOMIC_CLAUSE
         #undef OPENMP_SIMD_CLAUSE
         #undef OPENMP_FOR_CLAUSE


        Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
        +++ cfe/trunk/include/clang/Basic/StmtNodes.td Tue Jul 22
        05:10:35 2014
        @@ -194,3 +194,4 @@ def OMPBarrierDirective : DStmt<OMPExecu
         def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
         def OMPFlushDirective : DStmt<OMPExecutableDirective>;
         def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
        +def OMPAtomicDirective : DStmt<OMPExecutableDirective>;

        Modified: cfe/trunk/include/clang/Sema/Sema.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Sema/Sema.h (original)
        +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 22 05:10:35 2014
        @@ -7395,10 +7395,15 @@ public:
           StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *>
        Clauses,
        SourceLocation StartLoc,
        SourceLocation EndLoc);
        -  /// \brief Called on well-formed '\#pragma omp master'
        after parsing of the
        +  /// \brief Called on well-formed '\#pragma omp ordered'
        after parsing of the
           /// associated statement.
           StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt,
        SourceLocation StartLoc,
        SourceLocation EndLoc);
        +  /// \brief Called on well-formed '\#pragma omp atomic'
        after parsing of the
        +  /// associated statement.
        +  StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause
        *> Clauses,
        +                                        Stmt *AStmt,
        SourceLocation StartLoc,
        +  SourceLocation EndLoc);

           OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                                  Expr *Expr,

        Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h
        (original)
        +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue
        Jul 22 05:10:35 2014
        @@ -1356,6 +1356,7 @@ namespace clang {
               STMT_OMP_TASKWAIT_DIRECTIVE,
               STMT_OMP_FLUSH_DIRECTIVE,
               STMT_OMP_ORDERED_DIRECTIVE,
        +      STMT_OMP_ATOMIC_DIRECTIVE,

               // ARC
               EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr

        Modified: cfe/trunk/lib/AST/Stmt.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/AST/Stmt.cpp (original)
        +++ cfe/trunk/lib/AST/Stmt.cpp Tue Jul 22 05:10:35 2014
        @@ -1698,3 +1698,29 @@ OMPOrderedDirective *OMPOrderedDirective
           return new (Mem) OMPOrderedDirective();
         }

        +OMPAtomicDirective *OMPAtomicDirective::Create(const
        ASTContext &C,
        +   SourceLocation StartLoc,
        +   SourceLocation EndLoc,
        +   ArrayRef<OMPClause *> Clauses,
        +   Stmt *AssociatedStmt) {
        +  unsigned Size =
        llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),
        + llvm::alignOf<OMPClause *>());
        +  void *Mem =
        +      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size()
        + sizeof(Stmt *));
        +  OMPAtomicDirective *Dir =
        +      new (Mem) OMPAtomicDirective(StartLoc, EndLoc,
        Clauses.size());
        +  Dir->setClauses(Clauses);
        +  Dir->setAssociatedStmt(AssociatedStmt);
        +  return Dir;
        +}
        +
        +OMPAtomicDirective *OMPAtomicDirective::CreateEmpty(const
        ASTContext &C,
        +        unsigned NumClauses,
        +        EmptyShell) {
        +  unsigned Size =
        llvm::RoundUpToAlignment(sizeof(OMPAtomicDirective),
        + llvm::alignOf<OMPClause *>());
        +  void *Mem =
        +      C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
        sizeof(Stmt *));
        +  return new (Mem) OMPAtomicDirective(NumClauses);
        +}
        +

        Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
        +++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jul 22 05:10:35 2014
        @@ -891,6 +891,11 @@ void StmtPrinter::VisitOMPOrderedDirecti
           PrintOMPExecutableDirective(Node);
         }

        +void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective
        *Node) {
        +  Indent() << "#pragma omp atomic ";
        +  PrintOMPExecutableDirective(Node);
        +}
        +
         
//===----------------------------------------------------------------------===//
         //  Expr printing methods.
         
//===----------------------------------------------------------------------===//

        Modified: cfe/trunk/lib/AST/StmtProfile.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
        +++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jul 22 05:10:35 2014
        @@ -435,6 +435,10 @@ void StmtProfiler::VisitOMPOrderedDirect
           VisitOMPExecutableDirective(S);
         }

        +void StmtProfiler::VisitOMPAtomicDirective(const
        OMPAtomicDirective *S) {
        +  VisitOMPExecutableDirective(S);
        +}
        +
         void StmtProfiler::VisitExpr(const Expr *S) {
           VisitStmt(S);
         }

        Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
        +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Jul 22 05:10:35 2014
        @@ -260,6 +260,16 @@ bool clang::isAllowedClauseForDirective(
           case OMPD_flush:
             return CKind == OMPC_flush;
             break;
        +  case OMPD_atomic:
        +    switch (CKind) {
+#define OPENMP_ATOMIC_CLAUSE(Name) \
        +  case OMPC_##Name:                                  \
        +    return true;
        +#include "clang/Basic/OpenMPKinds.def"
        +    default:
        +      break;
        +    }
        +    break;
           case OMPD_unknown:
           case OMPD_threadprivate:
           case OMPD_section:

        Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
        +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Jul 22 05:10:35 2014
        @@ -224,6 +224,9 @@ void CodeGenFunction::EmitStmt(const Stm
           case Stmt::OMPOrderedDirectiveClass:
         EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));
             break;
        +  case Stmt::OMPAtomicDirectiveClass:
        +  EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S));
        +    break;
           }
         }


        Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
        +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Jul 22
        05:10:35 2014
        @@ -132,3 +132,7 @@ void CodeGenFunction::EmitOMPOrderedDire
           llvm_unreachable("CodeGen for 'omp ordered' is not
        supported yet.");
         }

        +void CodeGenFunction::EmitOMPAtomicDirective(const
        OMPAtomicDirective &) {
        +  llvm_unreachable("CodeGen for 'omp atomic' is not
        supported yet.");
        +}
        +

        Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
        +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 22
        05:10:35 2014
        @@ -1937,6 +1937,7 @@ public:
           void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
           void EmitOMPFlushDirective(const OMPFlushDirective &S);
           void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
        +  void EmitOMPAtomicDirective(const OMPAtomicDirective &S);

         
//===--------------------------------------------------------------------===//
           //                         LValue Expression Emission

        Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
        +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Jul 22 05:10:35 2014
        @@ -96,6 +96,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
           case OMPD_critical:
           case OMPD_parallel_for:
           case OMPD_parallel_sections:
        +  case OMPD_atomic:
             Diag(Tok, diag::err_omp_unexpected_directive)
                 << getOpenMPDirectiveName(DKind);
             break;
        @@ -114,7 +115,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
         ///         annot_pragma_openmp 'parallel' | 'simd' | 'for'
        | 'sections' |
         ///         'section' | 'single' | 'master' | 'critical' [
        '(' <name> ')' ] |
         ///         'parallel for' | 'parallel sections' | 'task' |
        'taskyield' |
        -///         'barrier' | 'taskwait' | 'flush' | 'ordered'
        {clause}
        +///         'barrier' | 'taskwait' | 'flush' | 'ordered' |
        'atomic' {clause}
         ///         annot_pragma_openmp_end
         ///
         StmtResult
        @@ -179,7 +180,8 @@ Parser::ParseOpenMPDeclarativeOrExecutab
           case OMPD_parallel_for:
           case OMPD_parallel_sections:
           case OMPD_task:
        -  case OMPD_ordered: {
        +  case OMPD_ordered:
        +  case OMPD_atomic: {
             ConsumeToken();
             // Parse directive name of the 'critical' directive if any.
             if (DKind == OMPD_critical) {

        Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
        +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jul 22 05:10:35 2014
        @@ -1114,6 +1114,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
                                      Params);
             break;
           }
        +  case OMPD_atomic: {
        +    Sema::CapturedParamNameType Params[] = {
        +        std::make_pair(StringRef(), QualType()) // __context
        with shared vars
        +    };
        +  ActOnCapturedRegionStart(DSAStack->getConstructLoc(),
        CurScope, CR_OpenMP,
        +                             Params);
        +    break;
        +  }
           case OMPD_threadprivate:
             llvm_unreachable("OpenMP Directive is not allowed");
           case OMPD_unknown:
        @@ -1145,6 +1153,7 @@ static bool CheckNestingOfRegions(Sema &
// | parallel | taskwait | * | // | parallel | flush | * | // | parallel | ordered | + | + // | parallel | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | for | parallel | * | // | for | for | + |
        @@ -1162,6 +1171,7 @@ static bool CheckNestingOfRegions(Sema &
// | for | taskwait | * | // | for | flush | * |
           // | for              | ordered         | * (if construct
        is ordered)        |
+ // | for | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | master | parallel | * | // | master | for | + |
        @@ -1179,6 +1189,7 @@ static bool CheckNestingOfRegions(Sema &
// | master | taskwait | * | // | master | flush | * | // | master | ordered | + | + // | master | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | critical | parallel | * | // | critical | for | + |
        @@ -1195,6 +1206,7 @@ static bool CheckNestingOfRegions(Sema &
// | critical | barrier | + | // | critical | taskwait | * | // | critical | ordered | + | + // | critical | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | simd | parallel | | // | simd | for | |
        @@ -1212,6 +1224,7 @@ static bool CheckNestingOfRegions(Sema &
// | simd | taskwait | | // | simd | flush | | // | simd | ordered | | + // | simd | atomic | |
           //
        
+------------------+-----------------+------------------------------------+
// | sections | parallel | * | // | sections | for | + |
        @@ -1229,6 +1242,7 @@ static bool CheckNestingOfRegions(Sema &
// | sections | taskwait | * | // | sections | flush | * | // | sections | ordered | + | + // | sections | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | section | parallel | * | // | section | for | + |
        @@ -1246,6 +1260,7 @@ static bool CheckNestingOfRegions(Sema &
// | section | taskwait | * | // | section | flush | * | // | section | ordered | + | + // | section | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | single | parallel | * | // | single | for | + |
        @@ -1263,6 +1278,7 @@ static bool CheckNestingOfRegions(Sema &
// | single | taskwait | * | // | single | flush | * | // | single | ordered | + | + // | single | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | parallel for | parallel | * | // | parallel for | for | + |
        @@ -1280,6 +1296,7 @@ static bool CheckNestingOfRegions(Sema &
// | parallel for | taskwait | * | // | parallel for | flush | * |
           // | parallel for     | ordered         | * (if construct
        is ordered)        |
+ // | parallel for | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * | // | parallel sections| for | + |
        @@ -1297,6 +1314,7 @@ static bool CheckNestingOfRegions(Sema &
// | parallel sections| taskwait | * | // | parallel sections| flush | * | // | parallel sections| ordered | + | + // | parallel sections| atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | task | parallel | * | // | task | for | + |
        @@ -1314,6 +1332,7 @@ static bool CheckNestingOfRegions(Sema &
// | task | taskwait | * | // | task | flush | * | // | task | ordered | + | + // | task | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
// | ordered | parallel | * | // | ordered | for | + |
        @@ -1331,6 +1350,7 @@ static bool CheckNestingOfRegions(Sema &
// | ordered | taskwait | * | // | ordered | flush | * | // | ordered | ordered | + | + // | ordered | atomic | * |
           //
        
+------------------+-----------------+------------------------------------+
           if (Stack->getCurScope()) {
             auto ParentRegion = Stack->getParentDirective();
        @@ -1347,6 +1367,12 @@ static bool CheckNestingOfRegions(Sema &
               SemaRef.Diag(StartLoc,
        diag::err_omp_prohibited_region_simd);
               return true;
             }
        +    if (ParentRegion == OMPD_atomic) {
        +      // OpenMP [2.16, Nesting of Regions]
        +      // OpenMP constructs may not be nested inside an
        atomic region.
        +      SemaRef.Diag(StartLoc,
        diag::err_omp_prohibited_region_atomic);
        +      return true;
        +    }
             if (CurrentRegion == OMPD_section) {
               // OpenMP [2.7.2, sections Construct, Restrictions]
               // Orphaned section directives are prohibited. That
        is, the section
        @@ -1368,7 +1394,7 @@ static bool CheckNestingOfRegions(Sema &
             if (CurrentRegion == OMPD_master) {
               // OpenMP [2.16, Nesting of Regions]
               // A master region may not be closely nested inside a
        worksharing,
        -      // atomic (TODO), or explicit task region.
        +      // atomic, or explicit task region.
               NestingProhibited =
        isOpenMPWorksharingDirective(ParentRegion) ||
                                   ParentRegion == OMPD_task;
             } else if (CurrentRegion == OMPD_critical &&
        CurrentName.getName()) {
        @@ -1403,7 +1429,7 @@ static bool CheckNestingOfRegions(Sema &
             } else if (CurrentRegion == OMPD_barrier) {
               // OpenMP [2.16, Nesting of Regions]
               // A barrier region may not be closely nested inside a
        worksharing,
        -      // explicit task, critical, ordered, atomic(TODO), or
        master region.
        +      // explicit task, critical, ordered, atomic, or master
        region.
               NestingProhibited =
         isOpenMPWorksharingDirective(ParentRegion) ||
                   ParentRegion == OMPD_task || ParentRegion ==
        OMPD_master ||
        @@ -1414,7 +1440,6 @@ static bool CheckNestingOfRegions(Sema &
               // OpenMP [2.16, Nesting of Regions]
               // A worksharing region may not be closely nested
        inside a worksharing,
               // explicit task, critical, ordered, atomic, or master
        region.
        -      // TODO
               NestingProhibited =
         (isOpenMPWorksharingDirective(ParentRegion) &&
        !isOpenMPSimdDirective(ParentRegion)) ||
        @@ -1424,7 +1449,7 @@ static bool CheckNestingOfRegions(Sema &
             } else if (CurrentRegion == OMPD_ordered) {
               // OpenMP [2.16, Nesting of Regions]
               // An ordered region may not be closely nested inside
        a critical,
        -      // atomic(TODO), or explicit task region.
        +      // atomic, or explicit task region.
               // An ordered region must be closely nested inside a
        loop region (or
               // parallel loop region) with an ordered clause.
               NestingProhibited = ParentRegion == OMPD_critical ||
        @@ -1558,6 +1583,10 @@ StmtResult Sema::ActOnOpenMPExecutableDi
                    "No clauses are allowed for 'omp ordered'
        directive");
             Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc);
             break;
        +  case OMPD_atomic:
        +    Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit,
        AStmt, StartLoc,
        +                                     EndLoc);
        +    break;
           case OMPD_threadprivate:
             llvm_unreachable("OpenMP Directive is not allowed");
           case OMPD_unknown:
        @@ -2345,6 +2374,23 @@ StmtResult Sema::ActOnOpenMPOrderedDirec
           return OMPOrderedDirective::Create(Context, StartLoc,
        EndLoc, AStmt);
         }

        +StmtResult
        Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
        +  Stmt *AStmt,
        +  SourceLocation StartLoc,
        +  SourceLocation EndLoc) {
        +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured
        statement expected");
        +  // 1.2.2 OpenMP Language Terminology
        +  // Structured block - An executable statement with a
        single entry at the
        +  // top and a single exit at the bottom.
        +  // The point of exit cannot be a branch out of the
        structured block.
        +  // longjmp() and throw() must not violate the entry/exit
        criteria.
        +  // TODO further analysis of associated statements and clauses.
        +
        +  getCurFunction()->setHasBranchProtectedScope();
        +
        +  return OMPAtomicDirective::Create(Context, StartLoc,
        EndLoc, Clauses, AStmt);
        +}
        +
         OMPClause
        *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
        Expr *Expr,
        SourceLocation StartLoc,
        SourceLocation LParenLoc,

        Modified: cfe/trunk/lib/Sema/TreeTransform.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Sema/TreeTransform.h (original)
        +++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jul 22 05:10:35 2014
        @@ -6644,6 +6644,17 @@ TreeTransform<Derived>::TransformOMPOrde
           return Res;
         }

        +template <typename Derived>
        +StmtResult
        +TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective
        *D) {
        +  DeclarationNameInfo DirName;
        +  getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic,
        DirName, nullptr,
        + D->getLocStart());
        +  StmtResult Res =
        getDerived().TransformOMPExecutableDirective(D);
        +  getDerived().getSema().EndOpenMPDSABlock(Res.get());
        +  return Res;
        +}
        +
         
//===----------------------------------------------------------------------===//
         // OpenMP clause transformation
         
//===----------------------------------------------------------------------===//

        Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
        +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jul 22
        05:10:35 2014
        @@ -2036,6 +2036,13 @@ void ASTStmtReader::VisitOMPOrderedDirec
           VisitOMPExecutableDirective(D);
         }

        +void
        ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
        +  VisitStmt(D);
        +  // The NumClauses field was read in ReadStmtFromStream.
        +  ++Idx;
        +  VisitOMPExecutableDirective(D);
        +}
        +
         
//===----------------------------------------------------------------------===//
         // ASTReader Implementation
         
//===----------------------------------------------------------------------===//
        @@ -2595,6 +2602,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
               S = OMPOrderedDirective::CreateEmpty(Context, Empty);
               break;

        +    case STMT_OMP_ATOMIC_DIRECTIVE:
        +      S = OMPAtomicDirective::CreateEmpty(
        +          Context, Record[ASTStmtReader::NumStmtFields], Empty);
        +      break;
        +
             case EXPR_CXX_OPERATOR_CALL:
               S = new (Context) CXXOperatorCallExpr(Context, Empty);
               break;

        Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
        +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jul 22
        05:10:35 2014
        @@ -1905,6 +1905,13 @@ void ASTStmtWriter::VisitOMPTaskDirectiv
           Code = serialization::STMT_OMP_TASK_DIRECTIVE;
         }

        +void
        ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
        +  VisitStmt(D);
        +  Record.push_back(D->getNumClauses());
        +  VisitOMPExecutableDirective(D);
        +  Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
        +}
        +
         void
        ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective
        *D) {
           VisitStmt(D);
           VisitOMPExecutableDirective(D);

        Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
        +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul
        22 05:10:35 2014
        @@ -747,6 +747,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
             case Stmt::OMPTaskwaitDirectiveClass:
             case Stmt::OMPFlushDirectiveClass:
             case Stmt::OMPOrderedDirectiveClass:
        +    case Stmt::OMPAtomicDirectiveClass:
               llvm_unreachable("Stmt should not be in analyzer
        evaluation loop");

             case Stmt::ObjCSubscriptRefExprClass:

        Added: cfe/trunk/test/OpenMP/atomic_ast_print.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_ast_print.cpp?rev=213639&view=auto
        
==============================================================================
        --- cfe/trunk/test/OpenMP/atomic_ast_print.cpp (added)
        +++ cfe/trunk/test/OpenMP/atomic_ast_print.cpp Tue Jul 22
        05:10:35 2014
        @@ -0,0 +1,34 @@
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s |
        FileCheck %s
        +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
        -emit-pch -o %t %s
        +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch
        %t -fsyntax-only -verify %s -ast-print | FileCheck %s
        +// expected-no-diagnostics
        +
        +#ifndef HEADER
        +#define HEADER
        +
        +template <class T>
        +T foo(T arg) {
        +  T a;
        +#pragma omp atomic
        +  a++;
        +  return T();
        +}
        +
        +// CHECK: int a;
        +// CHECK-NEXT: #pragma omp atomic
        +// CHECK-NEXT: a++;
        +// CHECK: T a;
        +// CHECK-NEXT: #pragma omp atomic
        +// CHECK-NEXT: a++;
        +
        +int main(int argc, char **argv) {
        +  int a;
        +// CHECK: int a;
        +#pragma omp atomic
        +  a++;
        +  // CHECK-NEXT: #pragma omp atomic
        +  // CHECK-NEXT: a++;
        +  return foo(a);
        +}
        +
        +#endif

        Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp
        
------------------------------------------------------------------------------
        svn:eol-style = native

        Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp
        
------------------------------------------------------------------------------
        svn:keywords = Author Date Id Rev URL

        Propchange: cfe/trunk/test/OpenMP/atomic_ast_print.cpp
        
------------------------------------------------------------------------------
        svn:mime-type = text/plain

        Added: cfe/trunk/test/OpenMP/atomic_messages.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=213639&view=auto
        
==============================================================================
        --- cfe/trunk/test/OpenMP/atomic_messages.cpp (added)
        +++ cfe/trunk/test/OpenMP/atomic_messages.cpp Tue Jul 22
        05:10:35 2014
        @@ -0,0 +1,20 @@
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit
        100 %s
        +
        +int foo() {
        +  L1:
        +    foo();
        +  #pragma omp atomic
        +  {
        +    foo();
        +    goto L1; // expected-error {{use of undeclared label 'L1'}}
        +  }
        +  goto L2; // expected-error {{use of undeclared label 'L2'}}
        +  #pragma omp atomic
        +  {
        +    foo();
        +    L2:
        +    foo();
        +  }
        +
        +  return 0;
        +}

        Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp
        
------------------------------------------------------------------------------
        svn:eol-style = native

        Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp
        
------------------------------------------------------------------------------
        svn:keywords = Author Date Id Rev URL

        Propchange: cfe/trunk/test/OpenMP/atomic_messages.cpp
        
------------------------------------------------------------------------------
        svn:mime-type = text/plain

        Modified: cfe/trunk/tools/libclang/CIndex.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/tools/libclang/CIndex.cpp (original)
        +++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jul 22 05:10:35 2014
        @@ -1872,6 +1872,7 @@ public:
           void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
           void VisitOMPFlushDirective(const OMPFlushDirective *D);
           void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
        +  void VisitOMPAtomicDirective(const OMPAtomicDirective *D);

         private:
           void AddDeclarationNameInfo(const Stmt *S);
        @@ -2378,6 +2379,10 @@ void EnqueueVisitor::VisitOMPOrderedDire
           VisitOMPExecutableDirective(D);
         }

        +void EnqueueVisitor::VisitOMPAtomicDirective(const
        OMPAtomicDirective *D) {
        +  VisitOMPExecutableDirective(D);
        +}
        +
         void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL,
        const Stmt *S) {
           EnqueueVisitor(WL, MakeCXCursor(S, StmtParent,
        TU,RegionOfInterest)).Visit(S);
         }
        @@ -4082,6 +4087,8 @@ CXString clang_getCursorKindSpelling(enu
             return cxstring::createRef("OMPFlushDirective");
           case CXCursor_OMPOrderedDirective:
             return cxstring::createRef("OMPOrderedDirective");
        +  case CXCursor_OMPAtomicDirective:
        +    return cxstring::createRef("OMPAtomicDirective");
           }

           llvm_unreachable("Unhandled CXCursorKind");

        Modified: cfe/trunk/tools/libclang/CXCursor.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=213639&r1=213638&r2=213639&view=diff
        
==============================================================================
        --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
        +++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Jul 22 05:10:35
        2014
        @@ -565,6 +565,9 @@ CXCursor cxcursor::MakeCXCursor(const St
           case Stmt::OMPOrderedDirectiveClass:
             K = CXCursor_OMPOrderedDirective;
             break;
        +  case Stmt::OMPAtomicDirectiveClass:
        +    K = CXCursor_OMPAtomicDirective;
        +    break;
           }

           CXCursor C = { K, 0, { Parent, S, TU } };


        _______________________________________________
        cfe-commits mailing list
        [email protected] <mailto:[email protected]>
        http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits






_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to