summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2014-07-22 06:45:04 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2014-07-22 06:45:04 +0000
commit9fb6e647e71678341e7a344051df439a1020aaf4 (patch)
tree917e4011ebedc52ff63737e7ee4f6e779e7861f6 /clang/lib
parent8b5126027406918e5b1f6ff4be2e98d231bb7704 (diff)
downloadbcm5719-llvm-9fb6e647e71678341e7a344051df439a1020aaf4.tar.gz
bcm5719-llvm-9fb6e647e71678341e7a344051df439a1020aaf4.zip
[OPENMP] Initial parsing and sema analysis for 'ordered' directive.
llvm-svn: 213616
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Stmt.cpp20
-rw-r--r--clang/lib/AST/StmtPrinter.cpp5
-rw-r--r--clang/lib/AST/StmtProfile.cpp4
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp1
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp3
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h1
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp7
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp116
-rw-r--r--clang/lib/Sema/TreeTransform.h11
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp9
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp6
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp1
13 files changed, 169 insertions, 19 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index a8483dc5bb9..2eba8753f6d 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1678,3 +1678,23 @@ OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
return new (Mem) OMPFlushDirective(NumClauses);
}
+OMPOrderedDirective *OMPOrderedDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPOrderedDirective *Dir = new (Mem) OMPOrderedDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPOrderedDirective *OMPOrderedDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPOrderedDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPOrderedDirective();
+}
+
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 1fdad9f4272..e8fbdf45390 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -886,6 +886,11 @@ void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
+ Indent() << "#pragma omp ordered";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index f44f25c96ab..0e308861fca 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -431,6 +431,10 @@ void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 06f010f7ceb..2f37f2fe66c 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -268,6 +268,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_ordered:
break;
}
return false;
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c2b64a7662b..d34a69ec3de 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -221,6 +221,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::OMPFlushDirectiveClass:
EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
break;
+ case Stmt::OMPOrderedDirectiveClass:
+ EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S));
+ break;
}
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 867f41592dd..8fdec176ed5 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -128,3 +128,7 @@ void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
}
+void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) {
+ llvm_unreachable("CodeGen for 'omp ordered' is not supported yet.");
+}
+
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 59cc30da42c..f2ecc4a796a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1936,6 +1936,7 @@ public:
void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
void EmitOMPFlushDirective(const OMPFlushDirective &S);
+ void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
//===--------------------------------------------------------------------===//
// LValue Expression Emission
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index d1544e6baa5..9afe26cee15 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -92,6 +92,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
case OMPD_section:
case OMPD_single:
case OMPD_master:
+ case OMPD_ordered:
case OMPD_critical:
case OMPD_parallel_for:
case OMPD_parallel_sections:
@@ -113,7 +114,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
-/// 'barrier' | 'taskwait' | 'flush' {clause} annot_pragma_openmp_end
+/// 'barrier' | 'taskwait' | 'flush' | 'ordered' {clause}
+/// annot_pragma_openmp_end
///
StmtResult
Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
@@ -176,7 +178,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
case OMPD_critical:
case OMPD_parallel_for:
case OMPD_parallel_sections:
- case OMPD_task: {
+ case OMPD_task:
+ case OMPD_ordered: {
ConsumeToken();
// Parse directive name of the 'critical' directive if any.
if (DKind == OMPD_critical) {
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7f2af68e55d..23ed63192b6 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -91,15 +91,16 @@ private:
DeclarationNameInfo DirectiveName;
Scope *CurScope;
SourceLocation ConstructLoc;
+ bool OrderedRegion;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
- ConstructLoc(Loc) {}
+ ConstructLoc(Loc), OrderedRegion(false) {}
SharingMapTy()
: SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
- ConstructLoc() {}
+ ConstructLoc(), OrderedRegion(false) {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -194,6 +195,18 @@ public:
return isOpenMPThreadPrivate(DVar.CKind);
}
+ /// \brief Marks current region as ordered (it has an 'ordered' clause).
+ void setOrderedRegion(bool IsOrdered = true) {
+ Stack.back().OrderedRegion = IsOrdered;
+ }
+ /// \brief Returns true, if parent region is ordered (has associated
+ /// 'ordered' clause), false - otherwise.
+ bool isParentOrderedRegion() const {
+ if (Stack.size() > 2)
+ return Stack[Stack.size() - 2].OrderedRegion;
+ return false;
+ }
+
Scope *getCurScope() const { return Stack.back().CurScope; }
Scope *getCurScope() { return Stack.back().CurScope; }
SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
@@ -1093,6 +1106,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
Params);
break;
}
+ case OMPD_ordered: {
+ 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:
@@ -1123,6 +1144,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel | barrier | * |
// | parallel | taskwait | * |
// | parallel | flush | * |
+ // | parallel | ordered | + |
// +------------------+-----------------+------------------------------------+
// | for | parallel | * |
// | for | for | + |
@@ -1139,6 +1161,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | for | barrier | + |
// | for | taskwait | * |
// | for | flush | * |
+ // | for | ordered | * (if construct is ordered) |
// +------------------+-----------------+------------------------------------+
// | master | parallel | * |
// | master | for | + |
@@ -1155,11 +1178,12 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | master | barrier | + |
// | master | taskwait | * |
// | master | flush | * |
+ // | master | ordered | + |
// +------------------+-----------------+------------------------------------+
// | critical | parallel | * |
// | critical | for | + |
// | critical | master | * |
- // | critical | critical | * (should have dirrerent names) |
+ // | critical | critical | * (should have different names) |
// | critical | simd | * |
// | critical | sections | + |
// | critical | section | + |
@@ -1170,6 +1194,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | critical | taskyield | * |
// | critical | barrier | + |
// | critical | taskwait | * |
+ // | critical | ordered | + |
// +------------------+-----------------+------------------------------------+
// | simd | parallel | |
// | simd | for | |
@@ -1186,6 +1211,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | simd | barrier | |
// | simd | taskwait | |
// | simd | flush | |
+ // | simd | ordered | |
// +------------------+-----------------+------------------------------------+
// | sections | parallel | * |
// | sections | for | + |
@@ -1202,6 +1228,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | sections | barrier | + |
// | sections | taskwait | * |
// | sections | flush | * |
+ // | sections | ordered | + |
// +------------------+-----------------+------------------------------------+
// | section | parallel | * |
// | section | for | + |
@@ -1218,6 +1245,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | section | barrier | + |
// | section | taskwait | * |
// | section | flush | * |
+ // | section | ordered | + |
// +------------------+-----------------+------------------------------------+
// | single | parallel | * |
// | single | for | + |
@@ -1234,6 +1262,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | single | barrier | + |
// | single | taskwait | * |
// | single | flush | * |
+ // | single | ordered | + |
// +------------------+-----------------+------------------------------------+
// | parallel for | parallel | * |
// | parallel for | for | + |
@@ -1250,6 +1279,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel for | barrier | + |
// | parallel for | taskwait | * |
// | parallel for | flush | * |
+ // | parallel for | ordered | * (if construct is ordered) |
// +------------------+-----------------+------------------------------------+
// | parallel sections| parallel | * |
// | parallel sections| for | + |
@@ -1266,6 +1296,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | parallel sections| barrier | + |
// | parallel sections| taskwait | * |
// | parallel sections| flush | * |
+ // | parallel sections| ordered | + |
// +------------------+-----------------+------------------------------------+
// | task | parallel | * |
// | task | for | + |
@@ -1282,12 +1313,34 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// | task | barrier | + |
// | task | taskwait | * |
// | task | flush | * |
+ // | task | ordered | + |
+ // +------------------+-----------------+------------------------------------+
+ // | ordered | parallel | * |
+ // | ordered | for | + |
+ // | ordered | master | * |
+ // | ordered | critical | * |
+ // | ordered | simd | * |
+ // | ordered | sections | + |
+ // | ordered | section | + |
+ // | ordered | single | + |
+ // | ordered | parallel for | * |
+ // | ordered |parallel sections| * |
+ // | ordered | task | * |
+ // | ordered | taskyield | * |
+ // | ordered | barrier | + |
+ // | ordered | taskwait | * |
+ // | ordered | flush | * |
+ // | ordered | ordered | + |
// +------------------+-----------------+------------------------------------+
if (Stack->getCurScope()) {
auto ParentRegion = Stack->getParentDirective();
bool NestingProhibited = false;
bool CloseNesting = true;
- bool ShouldBeInParallelRegion = false;
+ enum {
+ NoRecommend,
+ ShouldBeInParallelRegion,
+ ShouldBeInOrderedRegion
+ } Recommend = NoRecommend;
if (isOpenMPSimdDirective(ParentRegion)) {
// OpenMP [2.16, Nesting of Regions]
// OpenMP constructs may not be nested inside a simd region.
@@ -1308,6 +1361,10 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
}
return false;
}
+ // Allow some constructs to be orphaned (they could be used in functions,
+ // called from OpenMP regions with the required preconditions).
+ if (ParentRegion == OMPD_unknown)
+ return false;
if (CurrentRegion == OMPD_master) {
// OpenMP [2.16, Nesting of Regions]
// A master region may not be closely nested inside a worksharing,
@@ -1346,12 +1403,11 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
} 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(TODO), atomic(TODO), or master
- // region.
- NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
- ParentRegion == OMPD_task ||
- ParentRegion == OMPD_master ||
- ParentRegion == OMPD_critical;
+ // explicit task, critical, ordered, atomic(TODO), or master region.
+ NestingProhibited =
+ isOpenMPWorksharingDirective(ParentRegion) ||
+ ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
+ ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
} else if (isOpenMPWorksharingDirective(CurrentRegion) &&
!isOpenMPParallelDirective(CurrentRegion) &&
!isOpenMPSimdDirective(CurrentRegion)) {
@@ -1359,17 +1415,27 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// 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)) ||
+ NestingProhibited =
+ (isOpenMPWorksharingDirective(ParentRegion) &&
+ !isOpenMPSimdDirective(ParentRegion)) ||
+ ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
+ ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
+ Recommend = ShouldBeInParallelRegion;
+ } 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.
+ // An ordered region must be closely nested inside a loop region (or
+ // parallel loop region) with an ordered clause.
+ NestingProhibited = ParentRegion == OMPD_critical ||
ParentRegion == OMPD_task ||
- ParentRegion == OMPD_master ||
- ParentRegion == OMPD_critical;
- ShouldBeInParallelRegion = true;
+ !Stack->isParentOrderedRegion();
+ Recommend = ShouldBeInOrderedRegion;
}
if (NestingProhibited) {
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
- << CloseNesting << getOpenMPDirectiveName(ParentRegion)
- << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion);
+ << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend
+ << getOpenMPDirectiveName(CurrentRegion);
return true;
}
}
@@ -1487,6 +1553,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
"No associated statement allowed for 'omp flush' directive");
Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
break;
+ case OMPD_ordered:
+ assert(ClausesWithImplicit.empty() &&
+ "No clauses are allowed for 'omp ordered' directive");
+ Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc);
+ break;
case OMPD_threadprivate:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
@@ -2264,6 +2335,16 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
}
+StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+ getCurFunction()->setHasBranchProtectedScope();
+
+ return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -2727,6 +2808,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
SourceLocation EndLoc) {
+ DSAStack->setOrderedRegion();
return new (Context) OMPOrderedClause(StartLoc, EndLoc);
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 34d13c9085f..22a01bb636d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6633,6 +6633,17 @@ TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
return Res;
}
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clause transformation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 8bf17d51b3e..3d6a9a70fc0 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2031,6 +2031,11 @@ void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
+ VisitStmt(D);
+ VisitOMPExecutableDirective(D);
+}
+
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
@@ -2586,6 +2591,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
+ case STMT_OMP_ORDERED_DIRECTIVE:
+ S = OMPOrderedDirective::CreateEmpty(Context, Empty);
+ break;
+
case EXPR_CXX_OPERATOR_CALL:
S = new (Context) CXXOperatorCallExpr(Context, Empty);
break;
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index a43b3527a71..486f89d6770 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1930,6 +1930,12 @@ void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
+ VisitStmt(D);
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
+}
+
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 4e4095c5e0d..eac8dd0af61 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -746,6 +746,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::OMPBarrierDirectiveClass:
case Stmt::OMPTaskwaitDirectiveClass:
case Stmt::OMPFlushDirectiveClass:
+ case Stmt::OMPOrderedDirectiveClass:
llvm_unreachable("Stmt should not be in analyzer evaluation loop");
case Stmt::ObjCSubscriptRefExprClass:
OpenPOWER on IntegriCloud