diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Stmt.cpp | 20 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 10 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 5 | ||||
-rw-r--r-- | lib/Basic/OpenMPKinds.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGStmtOpenMP.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 114 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 29 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
13 files changed, 213 insertions, 17 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index a5ca49df20..b011f9f24c 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1496,6 +1496,26 @@ OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C, return new (Mem) OMPMasterDirective(); } +OMPCriticalDirective *OMPCriticalDirective::Create( + const ASTContext &C, const DeclarationNameInfo &Name, + SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective), + llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size + sizeof(Stmt *)); + OMPCriticalDirective *Dir = + new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc); + Dir->setAssociatedStmt(AssociatedStmt); + return Dir; +} + +OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C, + EmptyShell) { + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective), + llvm::alignOf<Stmt *>()); + void *Mem = C.Allocate(Size + sizeof(Stmt *)); + return new (Mem) OMPCriticalDirective(); +} + OMPParallelForDirective * OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 0267bcca2a..9c00eeaa0f 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -834,6 +834,16 @@ void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { PrintOMPExecutableDirective(Node); } +void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { + Indent() << "#pragma omp critical"; + if (Node->getDirectiveName().getName()) { + OS << " ("; + Node->getDirectiveName().printName(OS); + OS << ")"; + } + PrintOMPExecutableDirective(Node); +} + void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { Indent() << "#pragma omp parallel for "; PrintOMPExecutableDirective(Node); diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 0cd0f62dc5..56827ed383 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -393,6 +393,11 @@ void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) { + VisitOMPExecutableDirective(S); + VisitName(S->getDirectiveName().getName()); +} + void StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) { VisitOMPExecutableDirective(S); diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index f304513fcc..869b00c02a 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -257,6 +257,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_threadprivate: case OMPD_section: case OMPD_master: + case OMPD_critical: case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index cd970c747c..82566382db 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -197,6 +197,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::OMPMasterDirectiveClass: EmitOMPMasterDirective(cast<OMPMasterDirective>(*S)); break; + case Stmt::OMPCriticalDirectiveClass: + EmitOMPCriticalDirective(cast<OMPCriticalDirective>(*S)); + break; case Stmt::OMPParallelForDirectiveClass: EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S)); break; diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 7731c76f51..e4ef5a6911 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -94,6 +94,10 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) { llvm_unreachable("CodeGen for 'omp master' is not supported yet."); } +void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &) { + llvm_unreachable("CodeGen for 'omp critical' is not supported yet."); +} + void CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) { llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet."); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 3692b0203f..66bf78f002 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1928,6 +1928,7 @@ public: void EmitOMPSectionDirective(const OMPSectionDirective &S); void EmitOMPSingleDirective(const OMPSingleDirective &S); void EmitOMPMasterDirective(const OMPMasterDirective &S); + void EmitOMPCriticalDirective(const OMPCriticalDirective &S); void EmitOMPParallelForDirective(const OMPParallelForDirective &S); void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S); void EmitOMPTaskDirective(const OMPTaskDirective &S); diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index cf99178430..79cf6af6fd 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -91,6 +91,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { case OMPD_section: case OMPD_single: case OMPD_master: + case OMPD_critical: case OMPD_parallel_for: case OMPD_parallel_sections: Diag(Tok, diag::err_omp_unexpected_directive) @@ -109,9 +110,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() { /// /// executable-directive: /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | -/// 'section' | 'single' | 'master' | 'parallel for' | -/// 'parallel sections' | 'task' | 'taskyield' | 'barrier' | 'taskwait' -/// {clause} annot_pragma_openmp_end +/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] | +/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' | +/// 'barrier' | 'taskwait' {clause} annot_pragma_openmp_end /// StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { @@ -162,10 +163,26 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { case OMPD_single: case OMPD_section: case OMPD_master: + case OMPD_critical: case OMPD_parallel_for: case OMPD_parallel_sections: case OMPD_task: { ConsumeToken(); + // Parse directive name of the 'critical' directive if any. + if (DKind == OMPD_critical) { + BalancedDelimiterTracker T(*this, tok::l_paren, + tok::annot_pragma_openmp_end); + if (!T.consumeOpen()) { + if (Tok.isAnyIdentifier()) { + DirName = + DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation()); + ConsumeAnyToken(); + } else { + Diag(Tok, diag::err_omp_expected_identifier_for_critical); + } + T.consumeClose(); + } + } if (isOpenMPLoopDirective(DKind)) ScopeFlags |= Scope::OpenMPLoopDirectiveScope; @@ -215,7 +232,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { } if (CreateDirective) Directive = Actions.ActOnOpenMPExecutableDirective( - DKind, Clauses, AssociatedStmt.get(), Loc, EndLoc); + DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc); // Exit scope. Actions.EndOpenMPDSABlock(Directive.get()); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index f2421da582..c0a6d60a16 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -155,6 +155,9 @@ public: DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, DirectivesPredicate DPred, bool FromParent); + /// \brief Finds a directive which matches specified \a DPred predicate. + template <class NamedDirectivesPredicate> + bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); /// \brief Returns currently analyzed directive. OpenMPDirectiveKind getCurrentDirective() const { @@ -493,6 +496,20 @@ DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, return DSAVarData(); } +template <class NamedDirectivesPredicate> +bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { + auto StartI = std::next(Stack.rbegin()); + auto EndI = std::prev(Stack.rend()); + if (FromParent && StartI != EndI) { + StartI = std::next(StartI); + } + for (auto I = StartI, EE = EndI; I != EE; ++I) { + if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) + return true; + } + return false; +} + void Sema::InitDataSharingAttributesStack() { VarDataSharingAttributesStack = new DSAStackTy(*this); } @@ -1008,6 +1025,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { Params); break; } + case OMPD_critical: { + Sema::CapturedParamNameType Params[] = { + std::make_pair(StringRef(), QualType()) // __context with shared vars + }; + ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, + Params); + break; + } case OMPD_parallel_for: { QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); @@ -1067,9 +1092,10 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { } } -bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, - OpenMPDirectiveKind CurrentRegion, - SourceLocation StartLoc) { +static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, + OpenMPDirectiveKind CurrentRegion, + const DeclarationNameInfo &CurrentName, + SourceLocation StartLoc) { // Allowed nesting of constructs // +------------------+-----------------+------------------------------------+ // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| @@ -1077,6 +1103,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel | parallel | * | // | parallel | for | * | // | parallel | master | * | + // | parallel | critical | * | // | parallel | simd | * | // | parallel | sections | * | // | parallel | section | + | @@ -1091,6 +1118,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | for | parallel | * | // | for | for | + | // | for | master | + | + // | for | critical | * | // | for | simd | * | // | for | sections | + | // | for | section | + | @@ -1105,6 +1133,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | master | parallel | * | // | master | for | + | // | master | master | * | + // | master | critical | * | // | master | simd | * | // | master | sections | + | // | master | section | + | @@ -1116,9 +1145,25 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | master | barrier | + | // | master | taskwait | * | // +------------------+-----------------+------------------------------------+ + // | critical | parallel | * | + // | critical | for | + | + // | critical | master | * | + // | critical | critical | * (should have dirrerent names) | + // | critical | simd | * | + // | critical | sections | + | + // | critical | section | + | + // | critical | single | + | + // | critical | parallel for | * | + // | critical |parallel sections| * | + // | critical | task | * | + // | critical | taskyield | * | + // | critical | barrier | + | + // | critical | taskwait | * | + // +------------------+-----------------+------------------------------------+ // | simd | parallel | | // | simd | for | | // | simd | master | | + // | simd | critical | | // | simd | simd | | // | simd | sections | | // | simd | section | | @@ -1133,6 +1178,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | sections | parallel | * | // | sections | for | + | // | sections | master | + | + // | sections | critical | * | // | sections | simd | * | // | sections | sections | + | // | sections | section | * | @@ -1147,6 +1193,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | section | parallel | * | // | section | for | + | // | section | master | + | + // | section | critical | * | // | section | simd | * | // | section | sections | + | // | section | section | + | @@ -1161,6 +1208,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | single | parallel | * | // | single | for | + | // | single | master | + | + // | single | critical | * | // | single | simd | * | // | single | sections | + | // | single | section | + | @@ -1175,6 +1223,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel for | parallel | * | // | parallel for | for | + | // | parallel for | master | + | + // | parallel for | critical | * | // | parallel for | simd | * | // | parallel for | sections | + | // | parallel for | section | + | @@ -1189,6 +1238,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | parallel sections| parallel | * | // | parallel sections| for | + | // | parallel sections| master | + | + // | parallel sections| critical | + | // | parallel sections| simd | * | // | parallel sections| sections | + | // | parallel sections| section | * | @@ -1203,6 +1253,7 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | task | parallel | * | // | task | for | + | // | task | master | + | + // | task | critical | * | // | task | simd | * | // | task | sections | + | // | task | section | + | @@ -1245,14 +1296,44 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // atomic (TODO), or explicit task region. NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || ParentRegion == OMPD_task; + } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { + // OpenMP [2.16, Nesting of Regions] + // A critical region may not be nested (closely or otherwise) inside a + // critical region with the same name. Note that this restriction is not + // sufficient to prevent deadlock. + SourceLocation PreviousCriticalLoc; + bool DeadLock = + Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( + OpenMPDirectiveKind K, + const DeclarationNameInfo &DNI, + SourceLocation Loc) + ->bool { + if (K == OMPD_critical && + DNI.getName() == CurrentName.getName()) { + PreviousCriticalLoc = Loc; + return true; + } else + return false; + }, + false /* skip top directive */); + if (DeadLock) { + SemaRef.Diag(StartLoc, + diag::err_omp_prohibited_region_critical_same_name) + << CurrentName.getName(); + if (PreviousCriticalLoc.isValid()) + SemaRef.Diag(PreviousCriticalLoc, + diag::note_omp_previous_critical_region); + return true; + } } 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(TODO), ordered(TODO), atomic(TODO), or master + // explicit task, critical, ordered(TODO), atomic(TODO), or master // region. NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || ParentRegion == OMPD_task || - ParentRegion == OMPD_master; + ParentRegion == OMPD_master || + ParentRegion == OMPD_critical; } else if (isOpenMPWorksharingDirective(CurrentRegion) && !isOpenMPParallelDirective(CurrentRegion) && !isOpenMPSimdDirective(CurrentRegion)) { @@ -1263,7 +1344,8 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NestingProhibited = (isOpenMPWorksharingDirective(ParentRegion) && !isOpenMPSimdDirective(ParentRegion)) || ParentRegion == OMPD_task || - ParentRegion == OMPD_master; + ParentRegion == OMPD_master || + ParentRegion == OMPD_critical; ShouldBeInParallelRegion = true; } if (NestingProhibited) { @@ -1277,12 +1359,13 @@ bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, } StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, + const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { StmtResult Res = StmtError(); - if (CheckNestingOfRegions(*this, DSAStack, Kind, StartLoc)) + if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc)) return StmtError(); llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; @@ -1343,6 +1426,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, "No clauses are allowed for 'omp master' directive"); Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); break; + case OMPD_critical: + assert(ClausesWithImplicit.empty() && + "No clauses are allowed for 'omp critical' directive"); + Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc); + break; case OMPD_parallel_for: Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); @@ -2042,6 +2130,18 @@ StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); } +StmtResult +Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc) { + assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + + getCurFunction()->setHasBranchProtectedScope(); + + return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, + AStmt); +} + StmtResult Sema::ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 1f648d4aca..ba67df7417 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1298,12 +1298,12 @@ public: /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, + DeclarationNameInfo DirName, ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, - SourceLocation StartLoc, + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPExecutableDirective(Kind, Clauses, AStmt, - StartLoc, EndLoc); + return getSema().ActOnOpenMPExecutableDirective(Kind, DirName, Clauses, + AStmt, StartLoc, EndLoc); } /// \brief Build a new OpenMP 'if' clause. @@ -6445,9 +6445,16 @@ StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective( return StmtError(); } + // Transform directive name for 'omp critical' directive. + DeclarationNameInfo DirName; + if (D->getDirectiveKind() == OMPD_critical) { + DirName = cast<OMPCriticalDirective>(D)->getDirectiveName(); + DirName = getDerived().TransformDeclarationNameInfo(DirName); + } + return getDerived().RebuildOMPExecutableDirective( - D->getDirectiveKind(), TClauses, AssociatedStmt.get(), D->getLocStart(), - D->getLocEnd()); + D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(), + D->getLocStart(), D->getLocEnd()); } template <typename Derived> @@ -6528,6 +6535,16 @@ TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) { } template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) { + getDerived().getSema().StartOpenMPDSABlock( + OMPD_critical, D->getDirectiveName(), nullptr, D->getLocStart()); + StmtResult Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + +template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective( OMPParallelForDirective *D) { DeclarationNameInfo DirName; diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 99c9827ae2..e8a84282e7 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1968,6 +1968,12 @@ void ASTStmtReader::VisitOMPMasterDirective(OMPMasterDirective *D) { VisitOMPExecutableDirective(D); } +void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); + ReadDeclarationNameInfo(D->DirName, Record, Idx); +} + void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) { VisitStmt(D); // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream. @@ -2521,6 +2527,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = OMPMasterDirective::CreateEmpty(Context, Empty); break; + case STMT_OMP_CRITICAL_DIRECTIVE: + S = OMPCriticalDirective::CreateEmpty(Context, Empty); + break; + case STMT_OMP_PARALLEL_FOR_DIRECTIVE: { unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index db6adbcbaa..dd78c2446b 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1868,6 +1868,13 @@ void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) { Code = serialization::STMT_OMP_MASTER_DIRECTIVE; } +void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) { + VisitStmt(D); + VisitOMPExecutableDirective(D); + Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record); + Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) { VisitStmt(D); Record.push_back(D->getNumClauses()); diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 8da1d8e942..af2ef5e07a 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -738,6 +738,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPSectionDirectiveClass: case Stmt::OMPSingleDirectiveClass: case Stmt::OMPMasterDirectiveClass: + case Stmt::OMPCriticalDirectiveClass: case Stmt::OMPParallelForDirectiveClass: case Stmt::OMPParallelSectionsDirectiveClass: case Stmt::OMPTaskDirectiveClass: |