Author: Jennifer Yu Date: 2022-11-02T14:25:28-07:00 New Revision: ea64e66f7b71dfd52e9701a080b8216052344962
URL: https://github.com/llvm/llvm-project/commit/ea64e66f7b71dfd52e9701a080b8216052344962 DIFF: https://github.com/llvm/llvm-project/commit/ea64e66f7b71dfd52e9701a080b8216052344962.diff LOG: [OPENMP]Initial support for error directive. Differential Revision: https://reviews.llvm.org/D137209 Added: clang/test/OpenMP/error_ast_print.cpp clang/test/OpenMP/error_message.cpp Modified: clang/include/clang-c/Index.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/StmtOpenMP.h clang/include/clang/Basic/StmtNodes.td clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/StmtOpenMP.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGStmt.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/CodeGen/CodeGenFunction.h clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp llvm/include/llvm/Frontend/OpenMP/OMP.td Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 2cd2d499ab53d..e0f6f1c73549f 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1978,7 +1978,11 @@ enum CXCursorKind { */ CXCursor_OMPParallelMaskedTaskLoopSimdDirective = 304, - CXCursor_LastStmt = CXCursor_OMPParallelMaskedTaskLoopSimdDirective, + /** OpenMP error directive. + */ + CXCursor_OMPErrorDirective = 305, + + CXCursor_LastStmt = CXCursor_OMPErrorDirective, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 5eb8e0353ffd8..3d10d3bf98b29 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3153,6 +3153,10 @@ DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective, DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPErrorDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 702a82537ab2d..baa5e0ed7b63f 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -6220,6 +6220,51 @@ class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; } }; + +/// This represents '#pragma omp error' directive. +/// +/// \code +/// #pragma omp error +/// \endcode +class OMPErrorDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, + StartLoc, EndLoc) {} + /// Build an empty directive. + /// + explicit OMPErrorDirective() + : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, + SourceLocation(), SourceLocation()) {} + +public: + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// Creates an empty directive. + /// + /// \param C AST context. + /// + static OMPErrorDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPErrorDirectiveClass; + } +}; } // end namespace clang #endif diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ebbd8db313428..c434b07c95a40 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -292,3 +292,4 @@ def OMPTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>; def OMPTargetTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>; def OMPParallelGenericLoopDirective : StmtNode<OMPLoopDirective>; def OMPTargetParallelGenericLoopDirective : StmtNode<OMPLoopDirective>; +def OMPErrorDirective : StmtNode<OMPExecutableDirective>; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 46c139d6c62b0..e8c9cb966bae7 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11286,6 +11286,10 @@ class Sema final { /// Called on well-formed '\#pragma omp taskyield'. StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp error'. + StmtResult ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed '\#pragma omp barrier'. StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 21c6cdcf592fa..ceaade4a6e1e8 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1932,6 +1932,7 @@ enum StmtCode { STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE, STMT_OMP_TASK_DIRECTIVE, STMT_OMP_TASKYIELD_DIRECTIVE, + STMT_OMP_ERROR_DIRECTIVE, STMT_OMP_BARRIER_DIRECTIVE, STMT_OMP_TASKWAIT_DIRECTIVE, STMT_OMP_FLUSH_DIRECTIVE, diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index e0a4221db7ecf..88bb517e2280b 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -744,6 +744,21 @@ OMPTaskyieldDirective *OMPTaskyieldDirective::CreateEmpty(const ASTContext &C, return new (C) OMPTaskyieldDirective(); } +OMPErrorDirective *OMPErrorDirective::Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses) { + return createDirective<OMPErrorDirective>( + C, Clauses, /*AssociatedStmt=*/nullptr, /*NumChildren=*/0, StartLoc, + EndLoc); +} + +OMPErrorDirective *OMPErrorDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, + EmptyShell) { + return createEmptyDirective<OMPErrorDirective>(C, NumClauses); +} + OMPBarrierDirective *OMPBarrierDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index a29f762e10c14..70bed0eb60df0 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -843,6 +843,11 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) { + Indent() << "#pragma omp error"; + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { Indent() << "#pragma omp taskgroup"; PrintOMPExecutableDirective(Node); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 6af2beefc7926..01d44a95bbd4b 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1014,6 +1014,9 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) { + VisitOMPExecutableDirective(S); +} void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) { VisitOMPExecutableDirective(S); if (const Expr *E = S->getReductionRef()) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 2f2e6537ebd3e..7d74ec8701569 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -763,6 +763,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_allocate: case OMPD_taskyield: case OMPD_barrier: + case OMPD_error: case OMPD_taskwait: case OMPD_cancellation_point: case OMPD_cancel: diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 30c955b3d43fd..9531b855780c7 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -254,6 +254,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::OMPTaskyieldDirectiveClass: EmitOMPTaskyieldDirective(cast<OMPTaskyieldDirective>(*S)); break; + case Stmt::OMPErrorDirectiveClass: + EmitOMPErrorDirective(cast<OMPErrorDirective>(*S)); + break; case Stmt::OMPBarrierDirectiveClass: EmitOMPBarrierDirective(cast<OMPBarrierDirective>(*S)); break; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 40d84d754f9d3..4619be474b463 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1347,6 +1347,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit( case OMPD_parallel_for_simd: case OMPD_task: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_taskgroup: @@ -5244,6 +5245,10 @@ void CodeGenFunction::EmitOMPTaskyieldDirective( CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc()); } +void CodeGenFunction::EmitOMPErrorDirective(const OMPErrorDirective &S) { + llvm_unreachable("CodeGen for 'omp error' is not supported yet."); +} + void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8921cb78de996..560a9d97381c8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3520,6 +3520,7 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S); void EmitOMPTaskDirective(const OMPTaskDirective &S); void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S); + void EmitOMPErrorDirective(const OMPErrorDirective &S); void EmitOMPBarrierDirective(const OMPBarrierDirective &S); void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S); void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 6f8a467b9a657..7f48b16f97d61 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2310,6 +2310,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_unroll: case OMPD_task: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_taskgroup: @@ -2410,8 +2411,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] | /// 'parallel for' | 'parallel sections' | 'parallel master' | 'task' | -/// 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' | -/// 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target +/// 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'error' +/// | 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target /// data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' | /// 'master taskloop' | 'master taskloop simd' | 'parallel master /// taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target @@ -2697,6 +2698,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( case OMPD_depobj: case OMPD_scan: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index d8344cfd01f95..75ec180552f4f 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1494,6 +1494,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPTaskLoopSimdDirectiveClass: case Stmt::OMPTaskwaitDirectiveClass: case Stmt::OMPTaskyieldDirectiveClass: + case Stmt::OMPErrorDirectiveClass: case Stmt::OMPTeamsDirectiveClass: case Stmt::OMPTeamsDistributeDirectiveClass: case Stmt::OMPTeamsDistributeParallelForDirectiveClass: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index fd15c4d39b3b1..9906f636201c2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4532,6 +4532,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -6305,6 +6306,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( "No associated statement allowed for 'omp taskyield' directive"); Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); break; + case OMPD_error: + assert(AStmt == nullptr && + "No associated statement allowed for 'omp taskyield' directive"); + Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc); + break; case OMPD_barrier: assert(ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"); @@ -11020,6 +11026,12 @@ StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); } +StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc) { + return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses); +} + StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc) { @@ -15313,6 +15325,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15401,6 +15414,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15497,6 +15511,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15588,6 +15603,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15676,6 +15692,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15767,6 +15784,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15861,6 +15879,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: @@ -15952,6 +15971,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_threadprivate: case OMPD_allocate: case OMPD_taskyield: + case OMPD_error: case OMPD_barrier: case OMPD_taskwait: case OMPD_cancellation_point: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index f0d3a5ca089a3..ab34a9d611b9c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8897,6 +8897,17 @@ TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) { return Res; } +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr, + D->getBeginLoc()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective( OMPTaskgroupDirective *D) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f6a2f85682b2a..2a3c6e7231785 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2412,6 +2412,13 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPErrorDirective(OMPErrorDirective *D) { + VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); + VisitOMPExecutableDirective(D); +} + void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) { VisitStmt(D); VisitOMPExecutableDirective(D); @@ -3359,6 +3366,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumStmtFields], Empty); break; + case STMT_OMP_ERROR_DIRECTIVE: + S = OMPErrorDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); + break; + case STMT_OMP_TASKGROUP_DIRECTIVE: S = OMPTaskgroupDirective::CreateEmpty( Context, Record[ASTStmtReader::NumStmtFields], Empty); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index be28ad6b2a668..e2ba69ca1eec8 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2396,6 +2396,13 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE; } +void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) { + VisitStmt(D); + Record.push_back(D->getNumClauses()); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_ERROR_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) { VisitStmt(D); VisitOMPExecutableDirective(D); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5372c745f231f..1a2578b85f08f 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1744,6 +1744,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTaskyieldDirectiveClass: case Stmt::OMPBarrierDirectiveClass: case Stmt::OMPTaskwaitDirectiveClass: + case Stmt::OMPErrorDirectiveClass: case Stmt::OMPTaskgroupDirectiveClass: case Stmt::OMPFlushDirectiveClass: case Stmt::OMPDepobjDirectiveClass: diff --git a/clang/test/OpenMP/error_ast_print.cpp b/clang/test/OpenMP/error_ast_print.cpp new file mode 100644 index 0000000000000..fbdf68a11634d --- /dev/null +++ b/clang/test/OpenMP/error_ast_print.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +void foo() {} +// CHECK: template <typename T, int N> int tmain(T argc, char **argv) +// CHECK: static int a; +// CHECK-NEXT: #pragma omp error +// CHECK-NEXT: a = argv[0][0]; +// CHECK-NEXT: ++a; +// CHECK-NEXT: #pragma omp error +// CHECK-NEXT: { +// CHECK-NEXT: int b = 10; +// CHECK-NEXT: T c = 100; +// CHECK-NEXT: a = b + c; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp error +// CHECK-NEXT: foo(); +// CHECK-NEXT: return N; + +template <typename T, int N> +int tmain(T argc, char **argv) { + T b = argc, c, d, e, f, g; + static int a; +#pragma omp error + a = argv[0][0]; + ++a; +#pragma omp error + { + int b = 10; + T c = 100; + a = b + c; + } +#pragma omp error + foo(); +return N; +} + +// CHECK: int main(int argc, char **argv) +// CHECK-NEXT: int b = argc, c, d, e, f, g; +// CHECK-NEXT: static int a; +// CHECK-NEXT: #pragma omp error +// CHECK-NEXT: a = 2; +// CHECK-NEXT: #pragma omp error +// CHECK-NEXT: foo(); +int main (int argc, char **argv) { + int b = argc, c, d, e, f, g; + static int a; +#pragma omp error + a=2; +#pragma omp error + foo(); +} +#endif diff --git a/clang/test/OpenMP/error_message.cpp b/clang/test/OpenMP/error_message.cpp new file mode 100644 index 0000000000000..3f5a4cc243eb3 --- /dev/null +++ b/clang/test/OpenMP/error_message.cpp @@ -0,0 +1,114 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +template <class T> +T tmain(T argc) { + if (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + if (argc) { +#pragma omp error + } + while (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + while (argc) { +#pragma omp error + } + do +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + while (argc) + ; + do { +#pragma omp error + } while (argc); + switch (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + switch (argc) + case 1: +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + switch (argc) + case 1: { +#pragma omp error + } + switch (argc) { +#pragma omp error + case 1: +#pragma omp error + break; + default: { +#pragma omp error + } break; + } + for (;;) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + for (;;) { +#pragma omp error + } +label: +#pragma omp error +label1 : { +#pragma omp error +} +if (1) + label2: +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + + return T(); +} + +int main(int argc, char **argv) { +#pragma omp error + ; +#pragma omp error untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp error'}} +#pragma omp error unknown // expected-warning {{extra tokens at the end of '#pragma omp error' are ignored}} + if (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + if (argc) { +#pragma omp error + } + while (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + while (argc) { +#pragma omp error + } + do +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + while (argc) + ; + do { +#pragma omp error + } while (argc); + switch (argc) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + switch (argc) + case 1: +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + switch (argc) + case 1: { +#pragma omp error + } + switch (argc) { +#pragma omp error + case 1: +#pragma omp error + break; + default: { +#pragma omp error + } break; + } + for (;;) +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + for (;;) { +#pragma omp error + } +label: +#pragma omp error +label1 : { +#pragma omp error +} +if (1) + label2: +#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}} + + return tmain(argc); +} diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 728625ceb023f..ee6773531cfda 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2164,6 +2164,7 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> { void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D); void VisitOMPBarrierDirective(const OMPBarrierDirective *D); void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D); + void VisitOMPErrorDirective(const OMPErrorDirective *D); void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D); void VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D); @@ -3114,6 +3115,10 @@ void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) { VisitOMPExecutableDirective(D); } +void EnqueueVisitor::VisitOMPErrorDirective(const OMPErrorDirective *D) { + VisitOMPExecutableDirective(D); +} + void EnqueueVisitor::VisitOMPTaskgroupDirective( const OMPTaskgroupDirective *D) { VisitOMPExecutableDirective(D); @@ -5819,6 +5824,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OMPBarrierDirective"); case CXCursor_OMPTaskwaitDirective: return cxstring::createRef("OMPTaskwaitDirective"); + case CXCursor_OMPErrorDirective: + return cxstring::createRef("OMPErrorDirective"); case CXCursor_OMPTaskgroupDirective: return cxstring::createRef("OMPTaskgroupDirective"); case CXCursor_OMPFlushDirective: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index a90f414663ffe..3eda1e3e38d85 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -712,6 +712,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::OMPTaskwaitDirectiveClass: K = CXCursor_OMPTaskwaitDirective; break; + case Stmt::OMPErrorDirectiveClass: + K = CXCursor_OMPErrorDirective; + break; case Stmt::OMPTaskgroupDirectiveClass: K = CXCursor_OMPTaskgroupDirective; break; diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 0cf9d97317184..6de8a3ea93f1e 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -526,6 +526,7 @@ def OMP_Critical : Directive<"critical"> { } def OMP_TaskYield : Directive<"taskyield"> {} def OMP_Barrier : Directive<"barrier"> {} +def OMP_Error : Directive<"error"> {} def OMP_TaskWait : Directive<"taskwait"> { let allowedClauses = [ VersionedClause<OMPC_Depend, 50> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits