Ok, I understand, thanks. Then the code looks good.
On Wed, Jul 30, 2014 at 12:54 AM, Bataev, Alexey <[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]> > 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
