[OPENMP]Initial support for error directive.
Differential Revision: https://reviews.llvm.org/D137209
This commit is contained in:
parent
a588cfe37e
commit
ea64e66f7b
@ -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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -6220,6 +6220,51 @@ public:
|
||||
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
|
||||
|
||||
@ -292,3 +292,4 @@ def OMPTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
|
||||
def OMPTargetTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
|
||||
def OMPParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
|
||||
def OMPTargetParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
|
||||
def OMPErrorDirective : StmtNode<OMPExecutableDirective>;
|
||||
|
||||
@ -11286,6 +11286,10 @@ public:
|
||||
/// 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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -3520,6 +3520,7 @@ public:
|
||||
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);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
62
clang/test/OpenMP/error_ast_print.cpp
Normal file
62
clang/test/OpenMP/error_ast_print.cpp
Normal file
@ -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
|
||||
114
clang/test/OpenMP/error_message.cpp
Normal file
114
clang/test/OpenMP/error_message.cpp
Normal file
@ -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);
|
||||
}
|
||||
@ -2164,6 +2164,7 @@ public:
|
||||
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:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user