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]> 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] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
