<html><body>
<p><font size="2" face="sans-serif">Hi Alexey,</font><br>
<br>
<font size="2" face="sans-serif">I reviewed and tested this patch - everything seems fine - I only have some very minor comments (line numbers refer to revision 212940):</font><br>
<br>
<font size="2" face="sans-serif">- OpenMPKinds.def: line 127</font><br>
<br>
<font size="2" face="sans-serif">“TODO more clauses allowed for directive ‘omp single’.</font><br>
<br>
<font size="2" face="sans-serif">I think there are no more clauses allowed for single in OMP 4.0. Consider removing this comment.</font><br>
<br>
<font size="2" face="sans-serif">- SemaOpenMP.cpp: line 1898</font><br>
<br>
<font size="2" face="sans-serif">Missing</font><br>
<br>
<font size="2" face="sans-serif"> assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");</font><br>
<br>
<font size="2" face="sans-serif">in function ActOnOpenMPSingleDirective.</font><br>
<br>
<font size="2" face="sans-serif">This seems to be done for all previous directives. Unless I am missing something, it should be done also for “single”.</font><br>
<br>
<font size="2" face="sans-serif">- nesting_of_regions.cpp: line 314</font><br>
<br>
<font size="2" face="sans-serif">This check seems to be a duplicate from line 216.</font><br>
<br>
<br>
<font size="2" face="sans-serif">Thanks</font><br>
<br>
<font size="2" face="sans-serif">-- Carlo</font><br>
<br>
<br>
<tt><font size="2"><br>
> Date: Thu, 26 Jun 2014 12:05:46 -0000<br>
> From: Alexey Bataev <a.bataev@hotmail.com><br>
> To: cfe-commits@cs.uiuc.edu<br>
> Subject: r211774 - [OPENMP] Initial parsing and sema analysis for<br>
>    'single'   directive.<br>
> Message-ID: <20140626120547.2AB852A6C02A@llvm.org><br>
> Content-Type: text/plain; charset="utf-8"<br>
> <br>
> Author: abataev<br>
> Date: Thu Jun 26 07:05:45 2014<br>
> New Revision: 211774<br>
> <br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211774&view=rev">http://llvm.org/viewvc/llvm-project?rev=211774&view=rev</a><br>
> Log:<br>
> [OPENMP] Initial parsing and sema analysis for 'single' directive.<br>
> <br>
> Added:<br>
>     cfe/trunk/test/OpenMP/single_ast_print.cpp   (with props)<br>
>     cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp   (with props)<br>
>     cfe/trunk/test/OpenMP/single_misc_messages.c   (with props)<br>
>     cfe/trunk/test/OpenMP/single_private_messages.cpp   (with props)<br>
> Modified:<br>
>     cfe/trunk/include/clang-c/Index.h<br>
>     cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
>     cfe/trunk/include/clang/AST/StmtOpenMP.h<br>
>     cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
>     cfe/trunk/include/clang/Basic/StmtNodes.td<br>
>     cfe/trunk/include/clang/Sema/Sema.h<br>
>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
>     cfe/trunk/lib/AST/Stmt.cpp<br>
>     cfe/trunk/lib/AST/StmtPrinter.cpp<br>
>     cfe/trunk/lib/AST/StmtProfile.cpp<br>
>     cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
>     cfe/trunk/lib/CodeGen/CGStmt.cpp<br>
>     cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
>     cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
>     cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
>     cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
>     cfe/trunk/lib/Sema/TreeTransform.h<br>
>     cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
>     cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
>     cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
>     cfe/trunk/test/OpenMP/nesting_of_regions.cpp<br>
>     cfe/trunk/tools/libclang/CIndex.cpp<br>
>     cfe/trunk/tools/libclang/CXCursor.cpp<br>
> <br>
> Modified: cfe/trunk/include/clang-c/Index.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/</a><br>
> Index.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang-c/Index.h (original)<br>
> +++ cfe/trunk/include/clang-c/Index.h Thu Jun 26 07:05:45 2014<br>
> @@ -2151,7 +2151,11 @@ enum CXCursorKind {<br>
>     */<br>
>    CXCursor_OMPSectionDirective           = 236,<br>
>  <br>
> -  CXCursor_LastStmt                      = CXCursor_OMPSectionDirective,<br>
> +  /** \brief OpenMP single directive.<br>
> +   */<br>
> +  CXCursor_OMPSingleDirective            = 237,<br>
> +<br>
> +  CXCursor_LastStmt                      = CXCursor_OMPSingleDirective,<br>
>  <br>
>    /**<br>
>     * \brief Cursor that represents the translation unit itself.<br>
> <br>
> Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> AST/DataRecursiveASTVisitor.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)<br>
> +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Thu Jun 26<br>
> 07:05:45 2014<br>
> @@ -2305,6 +2305,11 @@ DEF_TRAVERSE_STMT(OMPSectionDirective, {<br>
>      return false;<br>
>  })<br>
>  <br>
> +DEF_TRAVERSE_STMT(OMPSingleDirective, {<br>
> +  if (!TraverseOMPExecutableDirective(S))<br>
> +    return false;<br>
> +})<br>
> +<br>
>  // OpenMP clauses.<br>
>  template <typename Derived><br>
>  bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {<br>
> <br>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> AST/RecursiveASTVisitor.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Jun 26 07:05:45 2014<br>
> @@ -2327,6 +2327,11 @@ DEF_TRAVERSE_STMT(OMPSectionDirective, {<br>
>      return false;<br>
>  })<br>
>  <br>
> +DEF_TRAVERSE_STMT(OMPSingleDirective, {<br>
> +  if (!TraverseOMPExecutableDirective(S))<br>
> +    return false;<br>
> +})<br>
> +<br>
>  // OpenMP clauses.<br>
>  template <typename Derived><br>
>  bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {<br>
> <br>
> Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> AST/StmtOpenMP.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)<br>
> +++ cfe/trunk/include/clang/AST/StmtOpenMP.h Thu Jun 26 07:05:45 2014<br>
> @@ -470,6 +470,63 @@ public:<br>
>    }<br>
>  };<br>
>  <br>
> +/// \brief This represents '#pragma omp single' directive.<br>
> +///<br>
> +/// \code<br>
> +/// #pragma omp single private(a,b) copyprivate(c,d)<br>
> +/// \endcode<br>
> +/// In this example directive '#pragma omp single' has clauses 'private' with<br>
> +/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.<br>
> +///<br>
> +class OMPSingleDirective : public OMPExecutableDirective {<br>
> +  friend class ASTStmtReader;<br>
> +  /// \brief Build directive with the given start and end location.<br>
> +  ///<br>
> +  /// \param StartLoc Starting location of the directive kind.<br>
> +  /// \param EndLoc Ending location of the directive.<br>
> +  /// \param NumClauses Number of clauses.<br>
> +  ///<br>
> +  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,<br>
> +                     unsigned NumClauses)<br>
> +      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,<br>
> +                               StartLoc, EndLoc, NumClauses, 1) {}<br>
> +<br>
> +  /// \brief Build an empty directive.<br>
> +  ///<br>
> +  /// \param NumClauses Number of clauses.<br>
> +  ///<br>
> +  explicit OMPSingleDirective(unsigned NumClauses)<br>
> +      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,<br>
> +                               SourceLocation(), SourceLocation(), <br>
> NumClauses,<br>
> +                               1) {}<br>
> +<br>
> +public:<br>
> +  /// \brief Creates directive with a list of \a Clauses.<br>
> +  ///<br>
> +  /// \param C AST context.<br>
> +  /// \param StartLoc Starting location of the directive kind.<br>
> +  /// \param EndLoc Ending Location of the directive.<br>
> +  /// \param Clauses List of clauses.<br>
> +  /// \param AssociatedStmt Statement, associated with the directive.<br>
> +  ///<br>
> +  static OMPSingleDirective *<br>
> +  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,<br>
> +         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);<br>
> +<br>
> +  /// \brief Creates an empty directive with the place for \a NumClauses<br>
> +  /// clauses.<br>
> +  ///<br>
> +  /// \param C AST context.<br>
> +  /// \param NumClauses Number of clauses.<br>
> +  ///<br>
> +  static OMPSingleDirective *CreateEmpty(const ASTContext &C,<br>
> +                                         unsigned NumClauses, EmptyShell);<br>
> +<br>
> +  static bool classof(const Stmt *T) {<br>
> +    return T->getStmtClass() == OMPSingleDirectiveClass;<br>
> +  }<br>
> +};<br>
> +<br>
>  } // end namespace clang<br>
>  <br>
>  #endif<br>
> <br>
> Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> Basic/OpenMPKinds.def?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)<br>
> +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Thu Jun 26 07:05:45 2014<br>
> @@ -30,6 +30,9 @@<br>
>  #ifndef OPENMP_SECTIONS_CLAUSE<br>
>  #  define OPENMP_SECTIONS_CLAUSE(Name)<br>
>  #endif<br>
> +#ifndef OPENMP_SINGLE_CLAUSE<br>
> +#  define OPENMP_SINGLE_CLAUSE(Name)<br>
> +#endif<br>
>  #ifndef OPENMP_DEFAULT_KIND<br>
>  #  define OPENMP_DEFAULT_KIND(Name)<br>
>  #endif<br>
> @@ -48,6 +51,7 @@ OPENMP_DIRECTIVE(simd)<br>
>  OPENMP_DIRECTIVE(for)<br>
>  OPENMP_DIRECTIVE(sections)<br>
>  OPENMP_DIRECTIVE(section)<br>
> +OPENMP_DIRECTIVE(single)<br>
>  <br>
>  // OpenMP clauses.<br>
>  OPENMP_CLAUSE(if, OMPIfClause)<br>
> @@ -104,6 +108,11 @@ OPENMP_SECTIONS_CLAUSE(firstprivate)<br>
>  OPENMP_SECTIONS_CLAUSE(reduction)<br>
>  OPENMP_SECTIONS_CLAUSE(nowait)<br>
>  <br>
> +// TODO more clauses allowed for directive 'omp single'.<br>
> +OPENMP_SINGLE_CLAUSE(private)<br>
> +OPENMP_SINGLE_CLAUSE(firstprivate)<br>
> +OPENMP_SINGLE_CLAUSE(nowait)<br>
> +<br>
>  // Static attributes for 'default' clause.<br>
>  OPENMP_DEFAULT_KIND(none)<br>
>  OPENMP_DEFAULT_KIND(shared)<br>
> @@ -125,6 +134,7 @@ OPENMP_SCHEDULE_KIND(runtime)<br>
>  #undef OPENMP_DEFAULT_KIND<br>
>  #undef OPENMP_DIRECTIVE<br>
>  #undef OPENMP_CLAUSE<br>
> +#undef OPENMP_SINGLE_CLAUSE<br>
>  #undef OPENMP_SECTIONS_CLAUSE<br>
>  #undef OPENMP_PARALLEL_CLAUSE<br>
>  #undef OPENMP_SIMD_CLAUSE<br>
> <br>
> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> Basic/StmtNodes.td?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Thu Jun 26 07:05:45 2014<br>
> @@ -182,3 +182,4 @@ def OMPSimdDirective : DStmt<OMPExecutab<br>
>  def OMPForDirective : DStmt<OMPExecutableDirective>;<br>
>  def OMPSectionsDirective : DStmt<OMPExecutableDirective>;<br>
>  def OMPSectionDirective : DStmt<OMPExecutableDirective>;<br>
> +def OMPSingleDirective : DStmt<OMPExecutableDirective>;<br>
> <br>
> Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> Sema/Sema.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 26 07:05:45 2014<br>
> @@ -7331,6 +7331,11 @@ public:<br>
>    /// associated statement.<br>
>    StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, <br>
> SourceLocation StartLoc,<br>
>                                           SourceLocation EndLoc);<br>
> +  /// \brief Called on well-formed '\#pragma omp single' after parsing of the<br>
> +  /// associated statement.<br>
> +  StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,<br>
> +                                        Stmt *AStmt, SourceLocationStartLoc,<br>
> +                                        SourceLocation EndLoc);<br>
>  <br>
>    OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,<br>
>                                           Expr *Expr,<br>
> <br>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/</a><br>
> Serialization/ASTBitCodes.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Jun 26 <br>
> 07:05:45 2014<br>
> @@ -1344,6 +1344,7 @@ namespace clang {<br>
>        STMT_OMP_FOR_DIRECTIVE,<br>
>        STMT_OMP_SECTIONS_DIRECTIVE,<br>
>        STMT_OMP_SECTION_DIRECTIVE,<br>
> +      STMT_OMP_SINGLE_DIRECTIVE,<br>
>  <br>
>        // ARC<br>
>        EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr<br>
> <br>
> Modified: cfe/trunk/lib/AST/Stmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?</a><br>
> rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/Stmt.cpp (original)<br>
> +++ cfe/trunk/lib/AST/Stmt.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -1430,3 +1430,29 @@ OMPSectionDirective *OMPSectionDirective<br>
>    return new (Mem) OMPSectionDirective();<br>
>  }<br>
>  <br>
> +OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,<br>
> +                                               SourceLocation StartLoc,<br>
> +                                               SourceLocation EndLoc,<br>
> +                                               ArrayRef<OMPClause *> Clauses,<br>
> +                                               Stmt *AssociatedStmt) {<br>
> +  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),<br>
> +                                           llvm::alignOf<OMPClause *>());<br>
> +  void *Mem =<br>
> +      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + <br>
> sizeof(Stmt *));<br>
> +  OMPSingleDirective *Dir =<br>
> +      new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());<br>
> +  Dir->setClauses(Clauses);<br>
> +  Dir->setAssociatedStmt(AssociatedStmt);<br>
> +  return Dir;<br>
> +}<br>
> +<br>
> +OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,<br>
> +                                                    unsigned NumClauses,<br>
> +                                                    EmptyShell) {<br>
> +  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),<br>
> +                                           llvm::alignOf<OMPClause *>());<br>
> +  void *Mem =<br>
> +      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));<br>
> +  return new (Mem) OMPSingleDirective(NumClauses);<br>
> +}<br>
> +<br>
> <br>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/</a><br>
> StmtPrinter.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -797,6 +797,11 @@ void StmtPrinter::VisitOMPSectionDirecti<br>
>    PrintOMPExecutableDirective(Node);<br>
>  }<br>
>  <br>
> +void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {<br>
> +  Indent() << "#pragma omp single ";<br>
> +  PrintOMPExecutableDirective(Node);<br>
> +}<br>
> +<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
>  //  Expr printing methods.<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
> <br>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/</a><br>
> StmtProfile.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -368,6 +368,10 @@ void StmtProfiler::VisitOMPSectionDirect<br>
>    VisitOMPExecutableDirective(S);<br>
>  }<br>
>  <br>
> +void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {<br>
> +  VisitOMPExecutableDirective(S);<br>
> +}<br>
> +<br>
>  void StmtProfiler::VisitExpr(const Expr *S) {<br>
>    VisitStmt(S);<br>
>  }<br>
> <br>
> Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/</a><br>
> OpenMPKinds.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)<br>
> +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -201,6 +201,16 @@ bool clang::isAllowedClauseForDirective(<br>
>        break;<br>
>      }<br>
>      break;<br>
> +  case OMPD_single:<br>
> +    switch (CKind) {<br>
> +#define OPENMP_SINGLE_CLAUSE(Name)                                         \<br>
> +  case OMPC_##Name:                                                        \<br>
> +    return true;<br>
> +#include "clang/Basic/OpenMPKinds.def"<br>
> +    default:<br>
> +      break;<br>
> +    }<br>
> +    break;<br>
>    case OMPD_unknown:<br>
>    case OMPD_threadprivate:<br>
>    case OMPD_task:<br>
> @@ -215,8 +225,8 @@ bool clang::isOpenMPLoopDirective(OpenMP<br>
>  }<br>
>  <br>
>  bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {<br>
> -  return DKind == OMPD_for || DKind == OMPD_sections ||<br>
> -         DKind == OMPD_section; // TODO add next directives.<br>
> +  return DKind == OMPD_for || DKind == OMPD_sections || DKind == <br>
> OMPD_section ||<br>
> +         DKind == OMPD_single; // TODO add next directives.<br>
>  }<br>
>  <br>
>  bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {<br>
> <br>
> Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> CGStmt.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -188,6 +188,9 @@ void CodeGenFunction::EmitStmt(const Stm<br>
>    case Stmt::OMPSectionDirectiveClass:<br>
>      EmitOMPSectionDirective(cast<OMPSectionDirective>(*S));<br>
>      break;<br>
> +  case Stmt::OMPSingleDirectiveClass:<br>
> +    EmitOMPSingleDirective(cast<OMPSingleDirective>(*S));<br>
> +    break;<br>
>    }<br>
>  }<br>
>  <br>
> <br>
> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> CGStmtOpenMP.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -87,3 +87,7 @@ void CodeGenFunction::EmitOMPSectionDire<br>
>    llvm_unreachable("CodeGen for 'omp section' is not supported yet.");<br>
>  }<br>
>  <br>
> +void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {<br>
> +  llvm_unreachable("CodeGen for 'omp single' is not supported yet.");<br>
> +}<br>
> +<br>
> <br>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/</a><br>
> CodeGenFunction.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jun 26 07:05:45 2014<br>
> @@ -1905,6 +1905,7 @@ public:<br>
>    void EmitOMPForDirective(const OMPForDirective &S);<br>
>    void EmitOMPSectionsDirective(const OMPSectionsDirective &S);<br>
>    void EmitOMPSectionDirective(const OMPSectionDirective &S);<br>
> +  void EmitOMPSingleDirective(const OMPSingleDirective &S);<br>
>  <br>
>    //<br>
> ===--------------------------------------------------------------------===//<br>
>    //                         LValue Expression Emission<br>
> <br>
> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/</a><br>
> ParseOpenMP.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -65,6 +65,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
>    case OMPD_for:<br>
>    case OMPD_sections:<br>
>    case OMPD_section:<br>
> +  case OMPD_single:<br>
>      Diag(Tok, diag::err_omp_unexpected_directive)<br>
>          << getOpenMPDirectiveName(DKind);<br>
>      break;<br>
> @@ -80,8 +81,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
>  ///         annot_pragma_openmp_end<br>
>  ///<br>
>  ///       executable-directive:<br>
> -///         annot_pragma_openmp 'parallel'|'simd'|'for'|'sections'|'section'<br>
> -///         {clause} annot_pragma_openmp_end<br>
> +///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |<br>
> +///         'section' | 'single' {clause} annot_pragma_openmp_end<br>
>  ///<br>
>  StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {<br>
>    assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");<br>
> @@ -121,6 +122,7 @@ StmtResult Parser::ParseOpenMPDeclarativ<br>
>    case OMPD_simd:<br>
>    case OMPD_for:<br>
>    case OMPD_sections:<br>
> +  case OMPD_single:<br>
>    case OMPD_section: {<br>
>      ConsumeToken();<br>
>  <br>
> <br>
> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/</a><br>
> SemaOpenMP.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -924,6 +924,13 @@ void Sema::ActOnOpenMPRegionStart(OpenMP<br>
>      ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
>      break;<br>
>    }<br>
> +  case OMPD_single: {<br>
> +    Sema::CapturedParamNameType Params[] = {<br>
> +        std::make_pair(StringRef(), QualType()) // __context with shared vars<br>
> +    };<br>
> +    ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);<br>
> +    break;<br>
> +  }<br>
>    case OMPD_threadprivate:<br>
>    case OMPD_task:<br>
>      llvm_unreachable("OpenMP Directive is not allowed");<br>
> @@ -1033,6 +1040,10 @@ StmtResult Sema::ActOnOpenMPExecutableDi<br>
>             "No clauses is allowed for 'omp section' directive");<br>
>      Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);<br>
>      break;<br>
> +  case OMPD_single:<br>
> +    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,<br>
> +                                     EndLoc);<br>
> +    break;<br>
>    case OMPD_threadprivate:<br>
>    case OMPD_task:<br>
>      llvm_unreachable("OpenMP Directive is not allowed");<br>
> @@ -1647,6 +1658,14 @@ StmtResult Sema::ActOnOpenMPSectionDirec<br>
>    return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);<br>
>  }<br>
>  <br>
> +StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,<br>
> +                                            Stmt *AStmt,<br>
> +                                            SourceLocation StartLoc,<br>
> +                                            SourceLocation EndLoc) {<br>
> +  getCurFunction()->setHasBranchProtectedScope();<br>
> +  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, <br>
> Clauses, AStmt);<br>
> +}<br>
> +<br>
>  OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,<br>
> Expr *Expr,<br>
>                                               SourceLocation StartLoc,<br>
>                                               SourceLocation LParenLoc,<br>
> <br>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/</a><br>
> TreeTransform.h?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
> +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 26 07:05:45 2014<br>
> @@ -6449,6 +6449,16 @@ TreeTransform<Derived>::TransformOMPSect<br>
>    return Res;<br>
>  }<br>
>  <br>
> +template <typename Derived><br>
> +StmtResult<br>
> +TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {<br>
> +  DeclarationNameInfo DirName;<br>
> +  getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr);<br>
> +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);<br>
> +  getDerived().getSema().EndOpenMPDSABlock(Res.get());<br>
> +  return Res;<br>
> +}<br>
> +<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
>  // OpenMP clause transformation</font></tt><br>
<tt><font size="2">>  //<br>
> ===----------------------------------------------------------------------===//<br>
> <br>
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/</a><br>
> Serialization/ASTReaderStmt.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -1918,6 +1918,13 @@ void ASTStmtReader::VisitOMPSectionDirec<br>
>    VisitOMPExecutableDirective(D);<br>
>  }<br>
>  <br>
> +void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {<br>
> +  VisitStmt(D);<br>
> +  // The NumClauses field was read in ReadStmtFromStream.<br>
> +  ++Idx;<br>
> +  VisitOMPExecutableDirective(D);<br>
> +}<br>
> +<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
>  // ASTReader Implementation<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
> @@ -2422,6 +2429,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu<br>
>        S = OMPSectionDirective::CreateEmpty(Context, Empty);<br>
>        break;<br>
>  <br>
> +    case STMT_OMP_SINGLE_DIRECTIVE:<br>
> +      S = OMPSingleDirective::CreateEmpty(<br>
> +          Context, Record[ASTStmtReader::NumStmtFields], Empty);<br>
> +      break;<br>
> +<br>
>      case EXPR_CXX_OPERATOR_CALL:<br>
>        S = new (Context) CXXOperatorCallExpr(Context, Empty);<br>
>        break;<br>
> <br>
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/</a><br>
> Serialization/ASTWriterStmt.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)<br>
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -1831,6 +1831,13 @@ void ASTStmtWriter::VisitOMPSectionDirec<br>
>    Code = serialization::STMT_OMP_SECTION_DIRECTIVE;<br>
>  }<br>
>  <br>
> +void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {<br>
> +  VisitStmt(D);<br>
> +  Record.push_back(D->getNumClauses());<br>
> +  VisitOMPExecutableDirective(D);<br>
> +  Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;<br>
> +}<br>
> +<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
>  // ASTWriter Implementation<br>
>  //<br>
> ===----------------------------------------------------------------------===//<br>
> <br>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/</a><br>
> StaticAnalyzer/Core/ExprEngine.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)<br>
> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -735,6 +735,7 @@ void ExprEngine::Visit(const Stmt *S, Ex<br>
>      case Stmt::OMPForDirectiveClass:<br>
>      case Stmt::OMPSectionsDirectiveClass:<br>
>      case Stmt::OMPSectionDirectiveClass:<br>
> +    case Stmt::OMPSingleDirectiveClass:<br>
>        llvm_unreachable("Stmt should not be in analyzer evaluation loop");<br>
>  <br>
>      case Stmt::ObjCSubscriptRefExprClass:<br>
> <br>
> Modified: cfe/trunk/test/OpenMP/nesting_of_regions.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/</a><br>
> nesting_of_regions.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (original)<br>
> +++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -22,6 +22,9 @@ void foo() {<br>
>    {<br>
>      bar();<br>
>    }<br>
> +#pragma omp parallel<br>
> +#pragma omp single<br>
> +  bar();<br>
>  #pragma omp simd<br>
>    for (int i = 0; i < 10; ++i) {<br>
>  #pragma omp for // expected-error {{OpenMP constructs may not be <br>
> nested inside a simd region}}<br>
> @@ -54,6 +57,13 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp simd<br>
> +  for (int i = 0; i < 10; ++i) {<br>
> +#pragma omp single // expected-error {{OpenMP constructs may not be<br>
> nested inside a simd region}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
>  #pragma omp for<br>
>    for (int i = 0; i < 10; ++i) {<br>
>  #pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'for' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> @@ -86,6 +96,13 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp for<br>
> +  for (int i = 0; i < 10; ++i) {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'for' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
>  #pragma omp sections<br>
>    {<br>
>  #pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'sections' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> @@ -118,10 +135,50 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp sections<br>
> +  {<br>
> +#pragma omp section<br>
> +    {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'section' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
>  #pragma omp section // expected-error {{orphaned 'omp section' <br>
> directives are prohibited, it must be closely nested to a sections region}}<br>
>    {<br>
>      bar();<br>
>    }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'single' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp simd<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp parallel<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'single' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp sections // expected-error {{region cannot be closely <br>
> nested inside 'single' region; perhaps you forget to enclose 'omp <br>
> sections' directive into a parallel region?}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
>  }<br>
>  <br>
>  void foo() {<br>
> @@ -143,6 +200,14 @@ void foo() {<br>
>    {<br>
>      bar();<br>
>    }<br>
> +#pragma omp parallel<br>
> +#pragma omp sections<br>
> +  {<br>
> +    bar();<br>
> +  }<br>
> +#pragma omp parallel<br>
> +#pragma omp single<br>
> +  bar();<br>
>  #pragma omp simd<br>
>    for (int i = 0; i < 10; ++i) {<br>
>  #pragma omp for // expected-error {{OpenMP constructs may not be <br>
> nested inside a simd region}}<br>
> @@ -175,6 +240,11 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp simd<br>
> +  for (int i = 0; i < 10; ++i) {<br>
> +#pragma omp single // expected-error {{OpenMP constructs may not be<br>
> nested inside a simd region}}<br>
> +    bar();<br>
> +  }<br>
>  #pragma omp for<br>
>    for (int i = 0; i < 10; ++i) {<br>
>  #pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'for' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> @@ -207,6 +277,11 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp for<br>
> +  for (int i = 0; i < 10; ++i) {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'for' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +    bar();<br>
> +  }<br>
>  #pragma omp sections<br>
>    {<br>
>  #pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'sections' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> @@ -239,10 +314,47 @@ void foo() {<br>
>        bar();<br>
>      }<br>
>    }<br>
> +#pragma omp sections<br>
> +  {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'sections' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +    bar();<br>
> +  }<br>
>  #pragma omp section // expected-error {{orphaned 'omp section' <br>
> directives are prohibited, it must be closely nested to a sections region}}<br>
>    {<br>
>      bar();<br>
>    }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp for // expected-error {{region cannot be closely nested<br>
> inside 'single' region; perhaps you forget to enclose 'omp for' <br>
> directive into a parallel region?}}<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp simd<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp parallel<br>
> +    for (int i = 0; i < 10; ++i)<br>
> +      ;<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp single // expected-error {{region cannot be closely <br>
> nested inside 'single' region; perhaps you forget to enclose 'omp <br>
> single' directive into a parallel region?}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
> +#pragma omp single<br>
> +  {<br>
> +#pragma omp sections // expected-error {{region cannot be closely <br>
> nested inside 'single' region; perhaps you forget to enclose 'omp <br>
> sections' directive into a parallel region?}}<br>
> +    {<br>
> +      bar();<br>
> +    }<br>
> +  }<br>
>    return foo<int>();<br>
>  }<br>
>  <br>
> <br>
> Added: cfe/trunk/test/OpenMP/single_ast_print.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/</a><br>
> single_ast_print.cpp?rev=211774&view=auto<br>
> ==============================================================================<br>
> --- cfe/trunk/test/OpenMP/single_ast_print.cpp (added)<br>
> +++ cfe/trunk/test/OpenMP/single_ast_print.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -0,0 +1,38 @@<br>
> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s<br>
> +// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s<br>
> +// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -<br>
> fsyntax-only -verify %s -ast-print | FileCheck %s<br>
> +// expected-no-diagnostics<br>
> +<br>
> +#ifndef HEADER<br>
> +#define HEADER<br>
> +<br>
> +void foo() {}<br>
> +<br>
> +template <class T, int N><br>
> +T tmain(T argc) {<br>
> +  T b = argc, c, d, e, f, g;<br>
> +  static T a;<br>
> +// CHECK: static T a;<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(argc, b), firstprivate(c, d), nowait<br>
> +  foo();<br>
> +  // CHECK-NEXT: #pragma omp parallel<br>
> +  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait<br>
> +  // CHECK-NEXT: foo();<br>
> +  return T();<br>
> +}<br>
> +<br>
> +int main(int argc, char **argv) {<br>
> +  int b = argc, c, d, e, f, g;<br>
> +  static int a;<br>
> +// CHECK: static int a;<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(argc, b), firstprivate(argv, c), nowait<br>
> +  foo();<br>
> +  // CHECK-NEXT: #pragma omp parallel<br>
> +  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate<br>
> (argv,c) nowait<br>
> +  // CHECK-NEXT: foo();<br>
> +  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));<br>
> +}<br>
> +<br>
> +#endif<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_ast_print.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:eol-style = native<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_ast_print.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:keywords = Author Date Id Rev URL<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_ast_print.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:mime-type = text/plain<br>
> <br>
> Added: cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/</a><br>
> single_firstprivate_messages.cpp?rev=211774&view=auto<br>
> ==============================================================================<br>
> --- cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp (added)<br>
> +++ cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp Thu Jun <br>
> 26 07:05:45 2014<br>
> @@ -0,0 +1,239 @@<br>
> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s<br>
> +<br>
> +void foo() {<br>
> +}<br>
> +<br>
> +bool foobool(int argc) {<br>
> +  return argc;<br>
> +}<br>
> +<br>
> +struct S1; // expected-note 2 {{declared here}} expected-note 2 <br>
> {{forward declaration of 'S1'}}<br>
> +extern S1 a;<br>
> +class S2 {<br>
> +  mutable int a;<br>
> +<br>
> +public:<br>
> +  S2() : a(0) {}<br>
> +  S2(S2 &s2) : a(s2.a) {}<br>
> +  static float S2s;<br>
> +  static const float S2sc;<br>
> +};<br>
> +const float S2::S2sc = 0;<br>
> +const S2 b;<br>
> +const S2 ba[5];<br>
> +class S3 {<br>
> +  int a;<br>
> +  S3 &operator=(const S3 &s3);<br>
> +<br>
> +public:<br>
> +  S3() : a(0) {}<br>
> +  S3(S3 &s3) : a(s3.a) {}<br>
> +};<br>
> +const S3 c;<br>
> +const S3 ca[5];<br>
> +extern const int f;<br>
> +class S4 { // expected-note 2 {{'S4' declared here}}<br>
> +  int a;<br>
> +  S4();<br>
> +  S4(const S4 &s4);<br>
> +<br>
> +public:<br>
> +  S4(int v) : a(v) {}<br>
> +};<br>
> +class S5 { // expected-note 4 {{'S5' declared here}}<br>
> +  int a;<br>
> +  S5(const S5 &s5) : a(s5.a) {}<br>
> +<br>
> +public:<br>
> +  S5() : a(0) {}<br>
> +  S5(int v) : a(v) {}<br>
> +};<br>
> +class S6 {<br>
> +  int a;<br>
> +  S6() : a(0) {}<br>
> +<br>
> +public:<br>
> +  S6(const S6 &s6) : a(s6.a) {}<br>
> +  S6(int v) : a(v) {}<br>
> +};<br>
> +<br>
> +S3 h;<br>
> +#pragma omp threadprivate(h) // expected-note 2 {{defined as <br>
> threadprivate or thread local}}<br>
> +<br>
> +template <class I, class C><br>
> +int foomain(int argc, char **argv) {<br>
> +  I e(4); // expected-note {{'e' defined here}}<br>
> +  C g(5); // expected-note 2 {{'g' defined here}}<br>
> +  int i;<br>
> +  int &j = i; // expected-note {{'j' defined here}}<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate // expected-error {{expected '(' <br>
> after 'firstprivate'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate( // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate() // expected-error {{expected expression}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc // expected-error {{expected <br>
> ')'}} expected-note {{to match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc, // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // <br>
> expected-error {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(S1) // expected-error {{'S1' does <br>
> not refer to a value}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(a, b) // expected-error <br>
> {{firstprivate variable with incomplete type 'S1'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argv[1]) // expected-error <br>
> {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(e, g) // expected-error 2 <br>
> {{firstprivate variable must have an accessible, unambiguous copy <br>
> constructor}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(h) // expected-error <br>
> {{threadprivate or thread local variable cannot be firstprivate}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single linear(i) // expected-error {{unexpected OpenMP <br>
> clause 'linear' in directive '#pragma omp single'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +  {<br>
> +    int v = 0;<br>
> +    int i;                         // expected-note {{variable with<br>
> automatic storage duration is predetermined as private; perhaps you <br>
> forget to enclose 'omp single' directive into a parallel or another <br>
> task region?}}<br>
> +#pragma omp single firstprivate(i) // expected-error {{private <br>
> variable cannot be firstprivate}}<br>
> +    foo();<br>
> +    v += i;<br>
> +  }<br>
> +#pragma omp parallel shared(i)<br>
> +#pragma omp parallel private(i)<br>
> +#pragma omp single firstprivate(j) // expected-error {{arguments of<br>
> OpenMP clause 'firstprivate' cannot be of reference type}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(i)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(g) // expected-error {{firstprivate<br>
> variable must have an accessible, unambiguous copy constructor}}<br>
> +  foo();<br>
> +#pragma omp parallel private(i)    // expected-note {{defined as private}}<br>
> +#pragma omp single firstprivate(i) // expected-error {{firstprivate<br>
> variable must be shared}}<br>
> +  foo();<br>
> +#pragma omp parallel reduction(+ : i) // expected-note {{defined as<br>
> reduction}}<br>
> +#pragma omp single firstprivate(i)    // expected-error <br>
> {{firstprivate variable must be shared}}<br>
> +  foo();<br>
> +  return 0;<br>
> +}<br>
> +<br>
> +int main(int argc, char **argv) {<br>
> +  const int d = 5;<br>
> +  const int da[5] = {0};<br>
> +  S4 e(4); // expected-note {{'e' defined here}}<br>
> +  S5 g(5); // expected-note 2 {{'g' defined here}}<br>
> +  S3 m;<br>
> +  S6 n(2);<br>
> +  int i;<br>
> +  int &j = i; // expected-note {{'j' defined here}}<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate // expected-error {{expected '(' <br>
> after 'firstprivate'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate( // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate() // expected-error {{expected expression}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc // expected-error {{expected <br>
> ')'}} expected-note {{to match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc, // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // <br>
> expected-error {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argc)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(S1) // expected-error {{'S1' does <br>
> not refer to a value}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(a, b, c, d, f) // expected-error <br>
> {{firstprivate variable with incomplete type 'S1'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(argv[1]) // expected-error <br>
> {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(2 * 2) // expected-error {{expected<br>
> variable name}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(ba) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(ca) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(da) // OK<br>
> +  foo();<br>
> +  int xa;<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(xa) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(S2::S2s) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(S2::S2sc) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single safelen(5) // expected-error {{unexpected OpenMP<br>
> clause 'safelen' in directive '#pragma omp single'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(e, g) // expected-error 2 <br>
> {{firstprivate variable must have an accessible, unambiguous copy <br>
> constructor}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(m) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(h) // expected-error <br>
> {{threadprivate or thread local variable cannot be firstprivate}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(xa), firstprivate(xa) // expected-error <br>
> {{private variable cannot be firstprivate}} expected-note {{defined <br>
> as private}}<br>
> +  foo();<br>
> +#pragma omp parallel shared(xa)<br>
> +#pragma omp single firstprivate(xa) // OK: may be firstprivate<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(j) // expected-error {{arguments of<br>
> OpenMP clause 'firstprivate' cannot be of reference type}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(g) // expected-error {{firstprivate<br>
> variable must have an accessible, unambiguous copy constructor}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single firstprivate(n) // OK<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +  {<br>
> +    int v = 0;<br>
> +    int i;                         // expected-note {{variable with<br>
> automatic storage duration is predetermined as private; perhaps you <br>
> forget to enclose 'omp single' directive into a parallel or another <br>
> task region?}}<br>
> +#pragma omp single firstprivate(i) // expected-error {{private <br>
> variable cannot be firstprivate}}<br>
> +    foo();<br>
> +    v += i;<br>
> +  }<br>
> +#pragma omp parallel private(i)    // expected-note {{defined as private}}<br>
> +#pragma omp single firstprivate(i) // expected-error {{firstprivate<br>
> variable must be shared}}<br>
> +  foo();<br>
> +#pragma omp parallel reduction(+ : i) // expected-note {{defined as<br>
> reduction}}<br>
> +#pragma omp single firstprivate(i)    // expected-error <br>
> {{firstprivate variable must be shared}}<br>
> +  foo();<br>
> +<br>
> +  return foomain<S4, S5>(argc, argv); // expected-note {{in <br>
> instantiation of function template specialization 'foomain<S4, S5>' <br>
> requested here}}<br>
> +}<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:eol-style = native<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:keywords = Author Date Id Rev URL<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_firstprivate_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:mime-type = text/plain<br>
> <br>
> Added: cfe/trunk/test/OpenMP/single_misc_messages.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/</a><br>
> single_misc_messages.c?rev=211774&view=auto<br>
> ==============================================================================<br>
> --- cfe/trunk/test/OpenMP/single_misc_messages.c (added)<br>
> +++ cfe/trunk/test/OpenMP/single_misc_messages.c Thu Jun 26 07:05:45 2014<br>
> @@ -0,0 +1,151 @@<br>
> +// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s<br>
> +<br>
> +void foo();<br>
> +<br>
> +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}<br>
> +#pragma omp single<br>
> +<br>
> +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}<br>
> +#pragma omp single foo<br>
> +<br>
> +void test_no_clause() {<br>
> +  int i;<br>
> +#pragma omp single<br>
> +  foo();<br>
> +<br>
> +#pragma omp single<br>
> +  ++i;<br>
> +}<br>
> +<br>
> +void test_branch_protected_scope() {<br>
> +  int i = 0;<br>
> +L1:<br>
> +  ++i;<br>
> +<br>
> +  int x[24];<br>
> +<br>
> +#pragma omp parallel<br>
> +#pragma omp single<br>
> +  {</font></tt><br>
<tt><font size="2">> +    if (i == 5)<br>
> +      goto L1; // expected-error {{use of undeclared label 'L1'}}<br>
> +    else if (i == 6)<br>
> +      return; // expected-error {{cannot return from OpenMP region}}<br>
> +    else if (i == 7)<br>
> +      goto L2;<br>
> +    else if (i == 8) {<br>
> +    L2:<br>
> +      x[i]++;<br>
> +    }<br>
> +  }<br>
> +<br>
> +  if (x[0] == 0)<br>
> +    goto L2; // expected-error {{use of undeclared label 'L2'}}<br>
> +  else if (x[1] == 1)<br>
> +    goto L1;<br>
> +}<br>
> +<br>
> +void test_invalid_clause() {<br>
> +  int i;<br>
> +#pragma omp parallel<br>
> +// expected-warning@+1 {{extra tokens at the end of '#pragma omp <br>
> single' are ignored}}<br>
> +#pragma omp single foo bar<br>
> +  foo();<br>
> +}<br>
> +<br>
> +void test_non_identifiers() {<br>
> +  int i, x;<br>
> +<br>
> +#pragma omp parallel<br>
> +// expected-warning@+1 {{extra tokens at the end of '#pragma omp <br>
> single' are ignored}}<br>
> +#pragma omp single;<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+2 {{unexpected OpenMP clause 'linear' in <br>
> directive '#pragma omp single'}}<br>
> +// expected-warning@+1 {{extra tokens at the end of '#pragma omp <br>
> single' are ignored}}<br>
> +#pragma omp single linear(x);<br>
> +  foo();<br>
> +<br>
> +#pragma omp parallel<br>
> +// expected-warning@+1 {{extra tokens at the end of '#pragma omp <br>
> single' are ignored}}<br>
> +#pragma omp single private(x);<br>
> +  foo();<br>
> +<br>
> +#pragma omp parallel<br>
> +// expected-warning@+1 {{extra tokens at the end of '#pragma omp <br>
> single' are ignored}}<br>
> +#pragma omp single, private(x);<br>
> +  foo();<br>
> +}<br>
> +<br>
> +void test_private() {<br>
> +  int i;<br>
> +#pragma omp parallel<br>
> +// expected-error@+2 {{expected expression}}<br>
> +// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}<br>
> +#pragma omp single private(<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}<br>
> +// expected-error@+1 2 {{expected expression}}<br>
> +#pragma omp single private(,<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 2 {{expected expression}}<br>
> +#pragma omp single private(, )<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected expression}}<br>
> +#pragma omp single private()<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected expression}}<br>
> +#pragma omp single private(int)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected variable name}}<br>
> +#pragma omp single private(0)<br>
> +  foo();<br>
> +<br>
> +  int x, y, z;<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(x)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(x, y)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +#pragma omp single private(x, y, z)<br>
> +  foo();<br>
> +}<br>
> +<br>
> +void test_firstprivate() {<br>
> +  int i;<br>
> +#pragma omp parallel<br>
> +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}<br>
> +// expected-error@+1 {{expected expression}}<br>
> +#pragma omp single firstprivate(<br>
> +  foo();<br>
> +<br>
> +#pragma omp parallel<br>
> +// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}<br>
> +// expected-error@+1 2 {{expected expression}}<br>
> +#pragma omp single firstprivate(,<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 2 {{expected expression}}<br>
> +#pragma omp single firstprivate(, )<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected expression}}<br>
> +#pragma omp single firstprivate()<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected expression}}<br>
> +#pragma omp single firstprivate(int)<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +// expected-error@+1 {{expected variable name}}<br>
> +#pragma omp single firstprivate(0)<br>
> +  foo();<br>
> +}<br>
> +<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_misc_messages.c<br>
> ------------------------------------------------------------------------------<br>
>     svn:eol-style = native<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_misc_messages.c<br>
> ------------------------------------------------------------------------------<br>
>     svn:keywords = Author Date Id Rev URL<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_misc_messages.c<br>
> ------------------------------------------------------------------------------<br>
>     svn:mime-type = text/plain<br>
> <br>
> Added: cfe/trunk/test/OpenMP/single_private_messages.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/</a><br>
> single_private_messages.cpp?rev=211774&view=auto<br>
> ==============================================================================<br>
> --- cfe/trunk/test/OpenMP/single_private_messages.cpp (added)<br>
> +++ cfe/trunk/test/OpenMP/single_private_messages.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -0,0 +1,140 @@<br>
> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s<br>
> +<br>
> +void foo() {<br>
> +}<br>
> +<br>
> +bool foobool(int argc) {<br>
> +  return argc;<br>
> +}<br>
> +<br>
> +struct S1; // expected-note 2 {{declared here}} expected-note 2 <br>
> {{forward declaration of 'S1'}}<br>
> +extern S1 a;<br>
> +class S2 {<br>
> +  mutable int a;<br>
> +<br>
> +public:<br>
> +  S2() : a(0) {}<br>
> +};<br>
> +const S2 b;<br>
> +const S2 ba[5];<br>
> +class S3 {<br>
> +  int a;<br>
> +<br>
> +public:<br>
> +  S3() : a(0) {}<br>
> +};<br>
> +const S3 ca[5];<br>
> +class S4 { // expected-note {{'S4' declared here}}<br>
> +  int a;<br>
> +  S4();<br>
> +<br>
> +public:<br>
> +  S4(int v) : a(v) {}<br>
> +};<br>
> +class S5 { // expected-note {{'S5' declared here}}<br>
> +  int a;<br>
> +  S5() : a(0) {}<br>
> +<br>
> +public:<br>
> +  S5(int v) : a(v) {}<br>
> +};<br>
> +<br>
> +S3 h;<br>
> +#pragma omp threadprivate(h) // expected-note 2 {{defined as <br>
> threadprivate or thread local}}<br>
> +<br>
> +template <class I, class C><br>
> +int foomain(I argc, C **argv) {<br>
> +  I e(4);<br>
> +  I g(5);<br>
> +  int i;<br>
> +  int &j = i;                // expected-note {{'j' defined here}}<br>
> +#pragma omp single private // expected-error {{expected '(' after 'private'}}<br>
> +  foo();<br>
> +#pragma omp single private( // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private() // expected-error {{expected expression}}<br>
> +  foo();<br>
> +#pragma omp single private(argc // expected-error {{expected ')'}} <br>
> expected-note {{to match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private(argc, // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // <br>
> expected-error {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp single private(argc)<br>
> +  foo();<br>
> +#pragma omp single private(S1) // expected-error {{'S1' does not <br>
> refer to a value}}<br>
> +  foo();<br>
> +#pragma omp single private(a, b) // expected-error {{private <br>
> variable with incomplete type 'S1'}}<br>
> +  foo();<br>
> +#pragma omp single private(argv[1]) // expected-error {{expected <br>
> variable name}}<br>
> +  foo();<br>
> +#pragma omp single private(e, g)<br>
> +  foo();<br>
> +#pragma omp single private(h) // expected-error {{threadprivate or <br>
> thread local variable cannot be private}}<br>
> +  foo();<br>
> +#pragma omp single shared(i) // expected-error {{unexpected OpenMP <br>
> clause 'shared' in directive '#pragma omp single'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +  {<br>
> +    int v = 0;<br>
> +    int i;<br>
> +#pragma omp single private(i)<br>
> +    foo();<br>
> +    v += i;<br>
> +  }<br>
> +#pragma omp parallel shared(i)<br>
> +#pragma omp parallel private(i)<br>
> +#pragma omp single private(j) // expected-error {{arguments of <br>
> OpenMP clause 'private' cannot be of reference type}}<br>
> +  foo();<br>
> +#pragma omp single private(i)<br>
> +  foo();<br>
> +  return 0;<br>
> +}<br>
> +<br>
> +int main(int argc, char **argv) {<br>
> +  S4 e(4); // expected-note {{'e' defined here}}<br>
> +  S5 g(5); // expected-note {{'g' defined here}}<br>
> +  int i;<br>
> +  int &j = i;                // expected-note {{'j' defined here}}<br>
> +#pragma omp single private // expected-error {{expected '(' after 'private'}}<br>
> +  foo();<br>
> +#pragma omp single private( // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private() // expected-error {{expected expression}}<br>
> +  foo();<br>
> +#pragma omp single private(argc // expected-error {{expected ')'}} <br>
> expected-note {{to match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private(argc, // expected-error {{expected <br>
> expression}} expected-error {{expected ')'}} expected-note {{to <br>
> match this '('}}<br>
> +  foo();<br>
> +#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // <br>
> expected-error {{expected variable name}}<br>
> +  foo();<br>
> +#pragma omp single private(argc)<br>
> +  foo();<br>
> +#pragma omp single private(S1) // expected-error {{'S1' does not <br>
> refer to a value}}<br>
> +  foo();<br>
> +#pragma omp single private(a, b) // expected-error {{private <br>
> variable with incomplete type 'S1'}}<br>
> +  foo();<br>
> +#pragma omp single private(argv[1]) // expected-error {{expected <br>
> variable name}}<br>
> +  foo();<br>
> +#pragma omp single private(e, g) // expected-error 2 {{private <br>
> variable must have an accessible, unambiguous default constructor}}<br>
> +  foo();<br>
> +#pragma omp single private(h) // expected-error {{threadprivate or <br>
> thread local variable cannot be private}}<br>
> +  foo();<br>
> +#pragma omp single shared(i) // expected-error {{unexpected OpenMP <br>
> clause 'shared' in directive '#pragma omp single'}}<br>
> +  foo();<br>
> +#pragma omp parallel<br>
> +  {<br>
> +    int i;<br>
> +#pragma omp single private(i)<br>
> +    foo();<br>
> +  }<br>
> +#pragma omp parallel shared(i)<br>
> +#pragma omp parallel private(i)<br>
> +#pragma omp single private(j) // expected-error {{arguments of <br>
> OpenMP clause 'private' cannot be of reference type}}<br>
> +  foo();<br>
> +#pragma omp single private(i)<br>
> +  foo();<br>
> +<br>
> +  return 0;<br>
> +}<br>
> +<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_private_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:eol-style = native<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_private_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:keywords = Author Date Id Rev URL<br>
> <br>
> Propchange: cfe/trunk/test/OpenMP/single_private_messages.cpp<br>
> ------------------------------------------------------------------------------<br>
>     svn:mime-type = text/plain<br>
> <br>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/</a><br>
> CIndex.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
> +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -1854,6 +1854,7 @@ public:<br>
>    void VisitOMPForDirective(const OMPForDirective *D);<br>
>    void VisitOMPSectionsDirective(const OMPSectionsDirective *D);<br>
>    void VisitOMPSectionDirective(const OMPSectionDirective *D);<br>
> +  void VisitOMPSingleDirective(const OMPSingleDirective *D);<br>
>  <br>
>  private:<br>
>    void AddDeclarationNameInfo(const Stmt *S);<br>
> @@ -2297,6 +2298,10 @@ void EnqueueVisitor::VisitOMPSectionDire<br>
>    VisitOMPExecutableDirective(D);<br>
>  }<br>
>  <br>
> +void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {<br>
> +  VisitOMPExecutableDirective(D);<br>
> +}<br>
> +<br>
>  void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {<br>
>    EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, <br>
> TU,RegionOfInterest)).Visit(S);<br>
>  }<br>
> @@ -3979,6 +3984,8 @@ CXString clang_getCursorKindSpelling(enu<br>
>      return cxstring::createRef("OMPSectionsDirective");<br>
>    case CXCursor_OMPSectionDirective:<br>
>      return cxstring::createRef("OMPSectionDirective");<br>
> +  case CXCursor_OMPSingleDirective:<br>
> +    return cxstring::createRef("OMPSingleDirective");<br>
>    }<br>
>  <br>
>    llvm_unreachable("Unhandled CXCursorKind");<br>
> <br>
> Modified: cfe/trunk/tools/libclang/CXCursor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/</a><br>
> CXCursor.cpp?rev=211774&r1=211773&r2=211774&view=diff<br>
> ==============================================================================<br>
> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)<br>
> +++ cfe/trunk/tools/libclang/CXCursor.cpp Thu Jun 26 07:05:45 2014<br>
> @@ -528,6 +528,9 @@ CXCursor cxcursor::MakeCXCursor(const St<br>
>    case Stmt::OMPSectionDirectiveClass:<br>
>      K = CXCursor_OMPSectionDirective;<br>
>      break;<br>
> +  case Stmt::OMPSingleDirectiveClass:<br>
> +    K = CXCursor_OMPSingleDirective;<br>
> +    break;<br>
>    }<br>
>  <br>
>    CXCursor C = { K, 0, { Parent, S, TU } };<br>
> <br>
> <br>
> <br>
> <br>
> ------------------------------<br>
> <br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> cfe-commits@cs.uiuc.edu<br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
> <br>
> <br>
> End of cfe-commits Digest, Vol 84, Issue 484<br>
> ********************************************<br>
> <br>
</font></tt></body></html>