[clang] ea64e66 - [OPENMP]Initial support for error directive.
Jennifer Yu via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 2 14:45:17 PDT 2022
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>
More information about the cfe-commits
mailing list