r190183 - OpenMP: Data-sharing attributes analysis and clause 'shared' (fixed test threadprivate_messages.cpp)

Nico Weber thakis at chromium.org
Wed Apr 23 18:08:18 PDT 2014


On Wed, Apr 23, 2014 at 5:43 PM, Richard Smith <metafoo at gmail.com> wrote:

> On Wed Apr 23 2014 at 5:25:44 PM, Nico Weber <thakis at chromium.org> wrote:
>
>> Good question, no idea. Do you want me to do this as part of this patch?
>>
>
> No, I agree with your later comment that this is separate. Better to get
> all the points where we leak marked with the 'bury' calls first so that we
> don't regress, then look at fixing them.
>
> Please go ahead with your burying patch!
>

r207056, thanks.

And a follow-up patch:

I looked at the confusing comment, and it looks like the comment was true
when it was first checked in in
https://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?revision=88772&view=markup&sortby=log&pathrev=88772but
then r110978 changed the order of the statements without updating the
comment. The if that leaks everything in AST mode even if !DisableFree was
there in the original checkin already.

(The resetAndLeak machinery was added in r128011.)

The attached patch fixes the comment, changes the bury branch to match the
order in the reseting branch (to match the new comment), and only leaks
objects in the AST case if DisableFree and relies on regular destructor
ordering for destruction on the other case. All tests seem to pass with
this patch.


>
>> If I just add a "if !disable free, reset all the leaked bits in that if
>> instead", then one of the module tests fails, due to
>>
>>    221   // Tell the SemaConsumer to forget about us; we're going out of
>> scope.
>>    222   if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
>> -> 223     SC->ForgetSema();
>>
>> running – the consumer was already reset earlier
>> in FrontendAction::EndSourceFile().
>>
>> There's also this comment saying that the consumer needs to be reset
>> before the AST because destructor ordering, and then code below that leaks
>> the consumer before the AST, but the !DisableFree branch resets the ASET
>> before resetting the consumer:
>>
>>   // Release the consumer and the AST, in that order since the consumer
>> may
>>   // perform actions in its destructor which require the context.
>>   //
>>   // FIXME: There is more per-file stuff we could just drop here?
>>   bool DisableFree = CI.getFrontendOpts().DisableFree;
>>   if (DisableFree) {
>>     BuryPointer(CI.takeASTConsumer());
>>     if (!isCurrentFileAST()) {
>>       CI.resetAndLeakSema();
>>       CI.resetAndLeakASTContext();
>>     }
>>   } else {
>>     if (!isCurrentFileAST()) {
>>       CI.setSema(0);
>>       CI.setASTContext(0);
>>     }
>>     CI.setASTConsumer(0);
>>   }
>>
>>
>> If you want, I can poke at that some more, but that seems a separate
>> issue from burying the sema if we're about to leak it.
>>
>>
>>
>> On Wed, Apr 23, 2014 at 4:57 PM, Richard Smith <metafoo at gmail.com> wrote:
>>
>>> Why are we leaking a bunch of stuff here? If we're not using
>>> -disable-free, we should be cleaning up after ourselves.
>>>
>>>
>>> On Wed Apr 23 2014 at 4:36:23 PM, Nico Weber <thakis at chromium.org>
>>> wrote:
>>>
>>>> (pretend that resetAndLeakSema() is a one-liner saying
>>>> "BuryPointer(TheSema.release())")
>>>>
>>>>
>>>> On Wed, Apr 23, 2014 at 4:34 PM, Nico Weber <thakis at chromium.org>wrote:
>>>>
>>>>> On Wed, Apr 23, 2014 at 3:46 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>>>>>
>>>>>> On Wed, Apr 23, 2014 at 3:21 PM, Nico Weber <thakis at chromium.org>wrote:
>>>>>>
>>>>>>> Hi Alexey,
>>>>>>>
>>>>>>> (below)
>>>>>>>
>>>>>>> On Fri, Sep 6, 2013 at 11:03 AM, Alexey Bataev <a.bataev at hotmail.com
>>>>>>> > wrote:
>>>>>>>
>>>>>>>> Author: abataev
>>>>>>>> Date: Fri Sep  6 13:03:48 2013
>>>>>>>> New Revision: 190183
>>>>>>>>
>>>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=190183&view=rev
>>>>>>>> Log:
>>>>>>>> OpenMP: Data-sharing attributes analysis and clause 'shared' (fixed
>>>>>>>> test threadprivate_messages.cpp)
>>>>>>>>
>>>>>>>> Added:
>>>>>>>>     cfe/trunk/test/OpenMP/parallel_messages.cpp   (with props)
>>>>>>>>     cfe/trunk/test/OpenMP/parallel_shared_messages.cpp   (with
>>>>>>>> props)
>>>>>>>> Modified:
>>>>>>>>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>>>>>>>>     cfe/trunk/include/clang/AST/StmtOpenMP.h
>>>>>>>>     cfe/trunk/include/clang/Basic/CapturedStmt.h
>>>>>>>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>>>>>>     cfe/trunk/include/clang/Basic/OpenMPKinds.def
>>>>>>>>     cfe/trunk/include/clang/Sema/Scope.h
>>>>>>>>     cfe/trunk/include/clang/Sema/ScopeInfo.h
>>>>>>>>     cfe/trunk/include/clang/Sema/Sema.h
>>>>>>>>     cfe/trunk/lib/AST/Stmt.cpp
>>>>>>>>     cfe/trunk/lib/AST/StmtPrinter.cpp
>>>>>>>>     cfe/trunk/lib/AST/StmtProfile.cpp
>>>>>>>>     cfe/trunk/lib/CodeGen/CGStmt.cpp
>>>>>>>>     cfe/trunk/lib/Parse/ParseOpenMP.cpp
>>>>>>>>     cfe/trunk/lib/Sema/Sema.cpp
>>>>>>>>     cfe/trunk/lib/Sema/SemaOpenMP.cpp
>>>>>>>>     cfe/trunk/lib/Sema/TreeTransform.h
>>>>>>>>     cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>>>>>>>>     cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>>>>>>>>     cfe/trunk/test/OpenMP/openmp_common.c
>>>>>>>>     cfe/trunk/test/OpenMP/parallel_default_messages.cpp
>>>>>>>>     cfe/trunk/test/OpenMP/parallel_private_messages.cpp
>>>>>>>>     cfe/trunk/tools/libclang/CIndex.cpp
>>>>>>>>     cfe/trunk/tools/libclang/RecursiveASTVisitor.h
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -2346,12 +2346,17 @@ bool RecursiveASTVisitor<Derived>::Visit
>>>>>>>>      TraverseStmt(*I);
>>>>>>>>
>>>>>>>>  template<typename Derived>
>>>>>>>> -bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(
>>>>>>>> -
>>>>>>>>  OMPPrivateClause *C) {
>>>>>>>> +bool
>>>>>>>> RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
>>>>>>>>    PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
>>>>>>>>    return true;
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +template<typename Derived>
>>>>>>>> +bool
>>>>>>>> RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
>>>>>>>> +  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
>>>>>>>> +  return true;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  #undef PROCESS_OMP_CLAUSE_LIST
>>>>>>>>
>>>>>>>>  // FIXME: look at the following tricky-seeming exprs to see if we
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/AST/StmtOpenMP.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/AST/StmtOpenMP.h Fri Sep  6 13:03:48
>>>>>>>> 2013
>>>>>>>> @@ -249,6 +249,63 @@ public:
>>>>>>>>    }
>>>>>>>>  };
>>>>>>>>
>>>>>>>> +/// \brief This represents clause 'shared' in the '#pragma omp
>>>>>>>> ...' directives.
>>>>>>>> +///
>>>>>>>> +/// \code
>>>>>>>> +/// #pragma omp parallel shared(a,b)
>>>>>>>> +/// \endcode
>>>>>>>> +/// In this example directive '#pragma omp parallel' has clause
>>>>>>>> 'shared'
>>>>>>>> +/// with the variables 'a' and 'b'.
>>>>>>>> +///
>>>>>>>> +class OMPSharedClause : public OMPClause, public
>>>>>>>> OMPVarList<OMPSharedClause> {
>>>>>>>> +  /// \brief Build clause with number of variables \a N.
>>>>>>>> +  ///
>>>>>>>> +  /// \param StartLoc Starting location of the clause.
>>>>>>>> +  /// \param LParenLoc Location of '('.
>>>>>>>> +  /// \param EndLoc Ending location of the clause.
>>>>>>>> +  /// \param N Number of the variables in the clause.
>>>>>>>> +  ///
>>>>>>>> +  OMPSharedClause(SourceLocation StartLoc, SourceLocation
>>>>>>>> LParenLoc,
>>>>>>>> +                  SourceLocation EndLoc, unsigned N)
>>>>>>>> +    : OMPClause(OMPC_shared, StartLoc, EndLoc),
>>>>>>>> +      OMPVarList<OMPSharedClause>(LParenLoc, N) { }
>>>>>>>> +
>>>>>>>> +  /// \brief Build an empty clause.
>>>>>>>> +  ///
>>>>>>>> +  /// \param N Number of variables.
>>>>>>>> +  ///
>>>>>>>> +  explicit OMPSharedClause(unsigned N)
>>>>>>>> +    : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
>>>>>>>> +      OMPVarList<OMPSharedClause>(SourceLocation(), N) { }
>>>>>>>> +public:
>>>>>>>> +  /// \brief Creates clause with a list of variables \a VL.
>>>>>>>> +  ///
>>>>>>>> +  /// \param C AST context.
>>>>>>>> +  /// \param StartLoc Starting location of the clause.
>>>>>>>> +  /// \param LParenLoc Location of '('.
>>>>>>>> +  /// \param EndLoc Ending location of the clause.
>>>>>>>> +  /// \param VL List of references to the variables.
>>>>>>>> +  ///
>>>>>>>> +  static OMPSharedClause *Create(const ASTContext &C,
>>>>>>>> SourceLocation StartLoc,
>>>>>>>> +                                 SourceLocation LParenLoc,
>>>>>>>> +                                 SourceLocation EndLoc,
>>>>>>>> ArrayRef<Expr *> VL);
>>>>>>>> +  /// \brief Creates an empty clause with \a N variables.
>>>>>>>> +  ///
>>>>>>>> +  /// \param C AST context.
>>>>>>>> +  /// \param N The number of variables.
>>>>>>>> +  ///
>>>>>>>> +  static OMPSharedClause *CreateEmpty(const ASTContext &C,
>>>>>>>> unsigned N);
>>>>>>>> +
>>>>>>>> +  StmtRange children() {
>>>>>>>> +    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
>>>>>>>> +                     reinterpret_cast<Stmt **>(varlist_end()));
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  static bool classof(const OMPClause *T) {
>>>>>>>> +    return T->getClauseKind() == OMPC_shared;
>>>>>>>> +  }
>>>>>>>> +};
>>>>>>>> +
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>  // AST classes for directives.
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Basic/CapturedStmt.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/CapturedStmt.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Basic/CapturedStmt.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/Basic/CapturedStmt.h Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -15,7 +15,8 @@ namespace clang {
>>>>>>>>
>>>>>>>>  /// \brief The different kinds of captured statement.
>>>>>>>>  enum CapturedRegionKind {
>>>>>>>> -  CR_Default
>>>>>>>> +  CR_Default,
>>>>>>>> +  CR_OpenMP
>>>>>>>>  };
>>>>>>>>
>>>>>>>>  } // end namespace clang
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>>>>>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -6612,6 +6612,14 @@ def err_omp_clause_ref_type_arg : Error<
>>>>>>>>    "arguments of OpenMP clause '%0' cannot be of reference type
>>>>>>>> %1">;
>>>>>>>>  def err_omp_threadprivate_incomplete_type : Error<
>>>>>>>>    "threadprivate variable with incomplete type %0">;
>>>>>>>> +def err_omp_no_dsa_for_variable : Error <
>>>>>>>> +  "variable %0 must have explicitly specified data sharing
>>>>>>>> attributes">;
>>>>>>>> +def err_omp_wrong_dsa : Error<
>>>>>>>> +  "%0 variable cannot be %1">;
>>>>>>>> +def note_omp_explicit_dsa : Note <
>>>>>>>> +  "defined as %0">;
>>>>>>>> +def note_omp_predetermined_dsa : Note <
>>>>>>>> +  "predetermined as %0">;
>>>>>>>>  } // end of OpenMP category
>>>>>>>>
>>>>>>>>  let CategoryName = "Related Result Type Issue" in {
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
>>>>>>>> +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -33,10 +33,12 @@ OPENMP_DIRECTIVE(task)
>>>>>>>>  // OpenMP clauses.
>>>>>>>>  OPENMP_CLAUSE(default, OMPDefaultClause)
>>>>>>>>  OPENMP_CLAUSE(private, OMPPrivateClause)
>>>>>>>> +OPENMP_CLAUSE(shared,  OMPSharedClause)
>>>>>>>>
>>>>>>>>  // Clauses allowed for OpenMP directives.
>>>>>>>>  OPENMP_PARALLEL_CLAUSE(default)
>>>>>>>>  OPENMP_PARALLEL_CLAUSE(private)
>>>>>>>> +OPENMP_PARALLEL_CLAUSE(shared)
>>>>>>>>
>>>>>>>>  // Static attributes for 'default' clause.
>>>>>>>>  OPENMP_DEFAULT_KIND(none)
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Sema/Scope.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Sema/Scope.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/Sema/Scope.h Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -91,7 +91,10 @@ public:
>>>>>>>>      TryScope = 0x2000,
>>>>>>>>
>>>>>>>>      /// \brief This is the scope for a function-level C++ try or
>>>>>>>> catch scope.
>>>>>>>> -    FnTryCatchScope = 0x4000
>>>>>>>> +    FnTryCatchScope = 0x4000,
>>>>>>>> +
>>>>>>>> +    /// \brief This is the scope of OpenMP executable directive
>>>>>>>> +    OpenMPDirectiveScope = 0x8000
>>>>>>>>    };
>>>>>>>>  private:
>>>>>>>>    /// The parent scope for this scope.  This is null for the
>>>>>>>> translation-unit
>>>>>>>> @@ -301,7 +304,12 @@ public:
>>>>>>>>      }
>>>>>>>>      return false;
>>>>>>>>    }
>>>>>>>> -
>>>>>>>> +
>>>>>>>> +  /// \brief Determines whether this scope is the OpenMP directive
>>>>>>>> scope
>>>>>>>> +  bool isOpenMPDirectiveScope() const {
>>>>>>>> +    return (getFlags() & Scope::OpenMPDirectiveScope);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>>    /// \brief Determine whether this scope is a C++ 'try' block.
>>>>>>>>    bool isTryScope() const { return getFlags() & Scope::TryScope; }
>>>>>>>>
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/Sema/ScopeInfo.h Fri Sep  6 13:03:48
>>>>>>>> 2013
>>>>>>>> @@ -567,6 +567,8 @@ public:
>>>>>>>>      switch (CapRegionKind) {
>>>>>>>>      case CR_Default:
>>>>>>>>        return "default captured statement";
>>>>>>>> +    case CR_OpenMP:
>>>>>>>> +      return "OpenMP region";
>>>>>>>>      }
>>>>>>>>      llvm_unreachable("Invalid captured region kind!");
>>>>>>>>    }
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>>>>>>> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -6887,6 +6887,20 @@ public:
>>>>>>>>                        unsigned SpellingListIndex, bool
>>>>>>>> IsPackExpansion);
>>>>>>>>
>>>>>>>>    // OpenMP directives and clauses.
>>>>>>>> +private:
>>>>>>>> +  void *VarDataSharingAttributesStack;
>>>>>>>> +  /// \brief Initialization of data-sharing attributes stack.
>>>>>>>> +  void InitDataSharingAttributesStack();
>>>>>>>> +  void DestroyDataSharingAttributesStack();
>>>>>>>> +public:
>>>>>>>> +  /// \brief Called on start of new data sharing attribute block.
>>>>>>>> +  void StartOpenMPDSABlock(OpenMPDirectiveKind K,
>>>>>>>> +                           const DeclarationNameInfo &DirName,
>>>>>>>> +                           Scope *CurScope);
>>>>>>>> +  /// \brief Called on end of data sharing attribute block.
>>>>>>>> +  void EndOpenMPDSABlock(Stmt *CurDirective);
>>>>>>>> +
>>>>>>>> +  // OpenMP directives and clauses.
>>>>>>>>    /// \brief Called on correct id-expression from the '#pragma omp
>>>>>>>>    /// threadprivate'.
>>>>>>>>    ExprResult ActOnOpenMPIdExpression(Scope *CurScope,
>>>>>>>> @@ -6936,6 +6950,11 @@ public:
>>>>>>>>                                        SourceLocation StartLoc,
>>>>>>>>                                        SourceLocation LParenLoc,
>>>>>>>>                                        SourceLocation EndLoc);
>>>>>>>> +  /// \brief Called on well-formed 'shared' clause.
>>>>>>>> +  OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
>>>>>>>> +                                     SourceLocation StartLoc,
>>>>>>>> +                                     SourceLocation LParenLoc,
>>>>>>>> +                                     SourceLocation EndLoc);
>>>>>>>>
>>>>>>>>    /// \brief The kind of conversion being performed.
>>>>>>>>    enum CheckedConversionKind {
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/AST/Stmt.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/AST/Stmt.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/AST/Stmt.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -1111,6 +1111,16 @@ bool CapturedStmt::capturesVariable(cons
>>>>>>>>    return false;
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +StmtRange OMPClause::children() {
>>>>>>>> +  switch(getClauseKind()) {
>>>>>>>> +  default : break;
>>>>>>>> +#define OPENMP_CLAUSE(Name, Class)
>>>>>>>>       \
>>>>>>>> +  case OMPC_ ## Name : return static_cast<Class
>>>>>>>> *>(this)->children();
>>>>>>>> +#include "clang/Basic/OpenMPKinds.def"
>>>>>>>> +  }
>>>>>>>> +  llvm_unreachable("unknown OMPClause");
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C,
>>>>>>>>                                             SourceLocation StartLoc,
>>>>>>>>                                             SourceLocation
>>>>>>>> LParenLoc,
>>>>>>>> @@ -1131,6 +1141,26 @@ OMPPrivateClause *OMPPrivateClause::Crea
>>>>>>>>    return new (Mem) OMPPrivateClause(N);
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
>>>>>>>> +                                         SourceLocation StartLoc,
>>>>>>>> +                                         SourceLocation LParenLoc,
>>>>>>>> +                                         SourceLocation EndLoc,
>>>>>>>> +                                         ArrayRef<Expr *> VL) {
>>>>>>>> +  void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *)
>>>>>>>> * VL.size(),
>>>>>>>> +                         llvm::alignOf<OMPSharedClause>());
>>>>>>>> +  OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc,
>>>>>>>> LParenLoc,
>>>>>>>> +                                                      EndLoc,
>>>>>>>> VL.size());
>>>>>>>> +  Clause->setVarRefs(VL);
>>>>>>>> +  return Clause;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
>>>>>>>> +                                              unsigned N) {
>>>>>>>> +  void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *)
>>>>>>>> * N,
>>>>>>>> +                         llvm::alignOf<OMPSharedClause>());
>>>>>>>> +  return new (Mem) OMPSharedClause(N);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *>
>>>>>>>> Clauses) {
>>>>>>>>    assert(Clauses.size() == this->Clauses.size() &&
>>>>>>>>           "Number of clauses is not the same as the preallocated
>>>>>>>> buffer");
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -614,6 +614,14 @@ void OMPClausePrinter::VisitOMPPrivateCl
>>>>>>>>    }
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node)
>>>>>>>> {
>>>>>>>> +  if (!Node->varlist_empty()) {
>>>>>>>> +    OS << "shared";
>>>>>>>> +    PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, Node, '(')
>>>>>>>> +    OS << ")";
>>>>>>>> +  }
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  #undef PROCESS_OMP_CLAUSE_LIST
>>>>>>>>  }
>>>>>>>>
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/AST/StmtProfile.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -272,6 +272,9 @@ void OMPClauseProfiler::VisitOMPDefaultC
>>>>>>>>  void OMPClauseProfiler::VisitOMPPrivateClause(const
>>>>>>>> OMPPrivateClause *C) {
>>>>>>>>    PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
>>>>>>>>  }
>>>>>>>> +void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause
>>>>>>>> *C) {
>>>>>>>> +  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
>>>>>>>> +}
>>>>>>>>  #undef PROCESS_OMP_CLAUSE_LIST
>>>>>>>>  }
>>>>>>>>
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -136,8 +136,10 @@ void CodeGenFunction::EmitStmt(const Stm
>>>>>>>>    case Stmt::SwitchStmtClass:
>>>>>>>> EmitSwitchStmt(cast<SwitchStmt>(*S));     break;
>>>>>>>>    case Stmt::GCCAsmStmtClass:   // Intentional fall-through.
>>>>>>>>    case Stmt::MSAsmStmtClass:    EmitAsmStmt(cast<AsmStmt>(*S));
>>>>>>>>         break;
>>>>>>>> -  case Stmt::CapturedStmtClass:
>>>>>>>> -    EmitCapturedStmt(cast<CapturedStmt>(*S), CR_Default);
>>>>>>>> +  case Stmt::CapturedStmtClass: {
>>>>>>>> +    const CapturedStmt *CS = cast<CapturedStmt>(S);
>>>>>>>> +    EmitCapturedStmt(*CS, CS->getCapturedRegionKind());
>>>>>>>> +    }
>>>>>>>>      break;
>>>>>>>>    case Stmt::ObjCAtTryStmtClass:
>>>>>>>>      EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -84,11 +84,14 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>>>>>>    SmallVector<OMPClause *, 5> Clauses;
>>>>>>>>    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
>>>>>>>> NUM_OPENMP_CLAUSES>
>>>>>>>>
>>>>>>>> FirstClauses(NUM_OPENMP_CLAUSES);
>>>>>>>> -  const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope;
>>>>>>>> +  const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
>>>>>>>> +                              Scope::OpenMPDirectiveScope;
>>>>>>>>    SourceLocation Loc = ConsumeToken(), EndLoc;
>>>>>>>>    OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
>>>>>>>>                                    OMPD_unknown :
>>>>>>>>
>>>>>>>>  getOpenMPDirectiveKind(PP.getSpelling(Tok));
>>>>>>>> +  // Name of critical directive.
>>>>>>>> +  DeclarationNameInfo DirName;
>>>>>>>>    StmtResult Directive = StmtError();
>>>>>>>>
>>>>>>>>    switch (DKind) {
>>>>>>>> @@ -111,6 +114,9 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>>>>>>      break;
>>>>>>>>    case OMPD_parallel: {
>>>>>>>>      ConsumeToken();
>>>>>>>> +
>>>>>>>> +    Actions.StartOpenMPDSABlock(DKind, DirName,
>>>>>>>> Actions.getCurScope());
>>>>>>>> +
>>>>>>>>      while (Tok.isNot(tok::annot_pragma_openmp_end)) {
>>>>>>>>        OpenMPClauseKind CKind = Tok.isAnnotation() ?
>>>>>>>>                                    OMPC_unknown :
>>>>>>>> @@ -138,7 +144,7 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>>>>>>      {
>>>>>>>>        // The body is a block scope like in Lambdas and Blocks.
>>>>>>>>        Sema::CompoundScopeRAII CompoundScope(Actions);
>>>>>>>> -      Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
>>>>>>>> CR_Default, 1);
>>>>>>>> +      Actions.ActOnCapturedRegionStart(Loc, getCurScope(),
>>>>>>>> CR_OpenMP, 1);
>>>>>>>>        Actions.ActOnStartOfCompoundStmt();
>>>>>>>>        // Parse statement
>>>>>>>>        AssociatedStmt = ParseStatement();
>>>>>>>> @@ -157,6 +163,7 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>>>>>>                                                           Loc,
>>>>>>>> EndLoc);
>>>>>>>>
>>>>>>>>      // Exit scope.
>>>>>>>> +    Actions.EndOpenMPDSABlock(Directive.get());
>>>>>>>>      OMPDirectiveScope.Exit();
>>>>>>>>      }
>>>>>>>>      break;
>>>>>>>> @@ -245,7 +252,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
>>>>>>>>  /// \brief Parsing of OpenMP clauses.
>>>>>>>>  ///
>>>>>>>>  ///    clause:
>>>>>>>> -///       default-clause|private-clause
>>>>>>>> +///       default-clause|private-clause|shared-clause
>>>>>>>>  ///
>>>>>>>>  OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
>>>>>>>>                                       OpenMPClauseKind CKind, bool
>>>>>>>> FirstClause) {
>>>>>>>> @@ -271,6 +278,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
>>>>>>>>      Clause = ParseOpenMPSimpleClause(CKind);
>>>>>>>>      break;
>>>>>>>>    case OMPC_private:
>>>>>>>> +  case OMPC_shared:
>>>>>>>>      Clause = ParseOpenMPVarListClause(CKind);
>>>>>>>>      break;
>>>>>>>>    case OMPC_unknown:
>>>>>>>> @@ -322,6 +330,8 @@ OMPClause *Parser::ParseOpenMPSimpleClau
>>>>>>>>  ///
>>>>>>>>  ///    private-clause:
>>>>>>>>  ///       'private' '(' list ')'
>>>>>>>> +///    shared-clause:
>>>>>>>> +///       'shared' '(' list ')'
>>>>>>>>  ///
>>>>>>>>  OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind)
>>>>>>>> {
>>>>>>>>    SourceLocation Loc = Tok.getLocation();
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Sema/Sema.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Sema/Sema.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/Sema/Sema.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -90,7 +90,8 @@ Sema::Sema(Preprocessor &pp, ASTContext
>>>>>>>>      AccessCheckingSFINAE(false),
>>>>>>>> InNonInstantiationSFINAEContext(false),
>>>>>>>>      NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
>>>>>>>>      CurrentInstantiationScope(0), TyposCorrected(0),
>>>>>>>> -    AnalysisWarnings(*this), CurScope(0), Ident_super(0),
>>>>>>>> Ident___float128(0)
>>>>>>>> +    AnalysisWarnings(*this), VarDataSharingAttributesStack(0),
>>>>>>>> CurScope(0),
>>>>>>>> +    Ident_super(0), Ident___float128(0)
>>>>>>>>  {
>>>>>>>>    TUScope = 0;
>>>>>>>>
>>>>>>>> @@ -113,6 +114,9 @@ Sema::Sema(Preprocessor &pp, ASTContext
>>>>>>>>                                            false, 0, false));
>>>>>>>>
>>>>>>>>    FunctionScopes.push_back(new FunctionScopeInfo(Diags));
>>>>>>>> +
>>>>>>>> +  // Initilization of data sharing attributes stack for OpenMP
>>>>>>>> +  InitDataSharingAttributesStack();
>>>>>>>>  }
>>>>>>>>
>>>>>>>>  void Sema::Initialize() {
>>>>>>>> @@ -199,6 +203,9 @@ Sema::~Sema() {
>>>>>>>>    // If Sema's ExternalSource is the multiplexer - we own it.
>>>>>>>>    if (isMultiplexExternalSource)
>>>>>>>>      delete ExternalSource;
>>>>>>>> +
>>>>>>>> +  // Destroys data sharing attributes stack for OpenMP
>>>>>>>> +  DestroyDataSharingAttributesStack();
>>>>>>>>  }
>>>>>>>>
>>>>>>>>  /// makeUnavailableInSystemHeader - There is an error in the
>>>>>>>> current
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -27,6 +27,325 @@
>>>>>>>>  #include "clang/Sema/ScopeInfo.h"
>>>>>>>>  using namespace clang;
>>>>>>>>
>>>>>>>>
>>>>>>>> +//===----------------------------------------------------------------------===//
>>>>>>>> +// Stack of data-sharing attributes for variables
>>>>>>>>
>>>>>>>> +//===----------------------------------------------------------------------===//
>>>>>>>> +
>>>>>>>> +namespace {
>>>>>>>> +/// \brief Default data sharing attributes, which can be applied
>>>>>>>> to directive.
>>>>>>>> +enum DefaultDataSharingAttributes {
>>>>>>>> +  DSA_unspecified = 0,   /// \brief Data sharing attribute not
>>>>>>>> specified.
>>>>>>>> +  DSA_none = 1 << 0,     /// \brief Default data sharing attribute
>>>>>>>> 'none'.
>>>>>>>> +  DSA_shared = 1 << 1    /// \brief Default data sharing attribute
>>>>>>>> 'shared'.
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +/// \brief Stack for tracking declarations used in OpenMP
>>>>>>>> directives and
>>>>>>>> +/// clauses and their data-sharing attributes.
>>>>>>>> +class DSAStackTy {
>>>>>>>> +public:
>>>>>>>> +  struct DSAVarData {
>>>>>>>> +    OpenMPDirectiveKind DKind;
>>>>>>>> +    OpenMPClauseKind CKind;
>>>>>>>> +    DeclRefExpr *RefExpr;
>>>>>>>> +    DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown),
>>>>>>>> RefExpr(0) { }
>>>>>>>> +  };
>>>>>>>> +private:
>>>>>>>> +  struct DSAInfo {
>>>>>>>> +    OpenMPClauseKind Attributes;
>>>>>>>> +    DeclRefExpr *RefExpr;
>>>>>>>> +  };
>>>>>>>> +  typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
>>>>>>>> +
>>>>>>>> +  struct SharingMapTy {
>>>>>>>> +    DeclSAMapTy SharingMap;
>>>>>>>> +    DefaultDataSharingAttributes DefaultAttr;
>>>>>>>> +    OpenMPDirectiveKind Directive;
>>>>>>>> +    DeclarationNameInfo DirectiveName;
>>>>>>>> +    Scope *CurScope;
>>>>>>>> +    SharingMapTy(OpenMPDirectiveKind DKind,
>>>>>>>> +                 const DeclarationNameInfo &Name,
>>>>>>>> +                 Scope *CurScope)
>>>>>>>> +      : SharingMap(), DefaultAttr(DSA_unspecified),
>>>>>>>> Directive(DKind),
>>>>>>>> +        DirectiveName(Name), CurScope(CurScope) { }
>>>>>>>> +    SharingMapTy()
>>>>>>>> +      : SharingMap(), DefaultAttr(DSA_unspecified),
>>>>>>>> +        Directive(OMPD_unknown), DirectiveName(),
>>>>>>>> +        CurScope(0) { }
>>>>>>>> +  };
>>>>>>>> +
>>>>>>>> +  typedef SmallVector<SharingMapTy, 64> StackTy;
>>>>>>>> +
>>>>>>>> +  /// \brief Stack of used declaration and their data-sharing
>>>>>>>> attributes.
>>>>>>>> +  StackTy Stack;
>>>>>>>> +  Sema &Actions;
>>>>>>>> +
>>>>>>>> +  typedef SmallVector<SharingMapTy, 8>::reverse_iterator
>>>>>>>> reverse_iterator;
>>>>>>>> +
>>>>>>>> +  DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
>>>>>>>> +public:
>>>>>>>> +  explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) { }
>>>>>>>> +
>>>>>>>> +  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo
>>>>>>>> &DirName,
>>>>>>>> +            Scope *CurScope) {
>>>>>>>> +    Stack.push_back(SharingMapTy(DKind, DirName, CurScope));
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  void pop() {
>>>>>>>> +    assert(Stack.size() > 1 && "Data-sharing attributes stack is
>>>>>>>> empty!");
>>>>>>>> +    Stack.pop_back();
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  /// \brief Adds explicit data sharing attribute to the specified
>>>>>>>> declaration.
>>>>>>>> +  void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
>>>>>>>> +
>>>>>>>> +  /// \brief Checks if the variable is a local for OpenMP region.
>>>>>>>> +  bool isOpenMPLocal(VarDecl *D);
>>>>>>>> +
>>>>>>>> +  /// \brief Returns data sharing attributes from top of the stack
>>>>>>>> for the
>>>>>>>> +  /// specified declaration.
>>>>>>>> +  DSAVarData getTopDSA(VarDecl *D);
>>>>>>>> +  /// \brief Returns data-sharing attributes for the specified
>>>>>>>> declaration.
>>>>>>>> +  DSAVarData getImplicitDSA(VarDecl *D);
>>>>>>>> +
>>>>>>>> +  /// \brief Returns currently analyzed directive.
>>>>>>>> +  OpenMPDirectiveKind getCurrentDirective() const {
>>>>>>>> +    return Stack.back().Directive;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  /// \brief Set default data sharing attribute to none.
>>>>>>>> +  void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
>>>>>>>> +  /// \brief Set default data sharing attribute to shared.
>>>>>>>> +  void setDefaultDSAShared() { Stack.back().DefaultAttr =
>>>>>>>> DSA_shared; }
>>>>>>>> +
>>>>>>>> +  DefaultDataSharingAttributes getDefaultDSA() const {
>>>>>>>> +    return Stack.back().DefaultAttr;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  Scope *getCurScope() { return Stack.back().CurScope; }
>>>>>>>> +};
>>>>>>>> +} // end anonymous namespace.
>>>>>>>> +
>>>>>>>> +DSAStackTy::DSAVarData
>>>>>>>> DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
>>>>>>>> +                                          VarDecl *D) {
>>>>>>>> +  DSAVarData DVar;
>>>>>>>> +  if (Iter == Stack.rend() - 1) {
>>>>>>>> +    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +    // in a region but not in construct]
>>>>>>>> +    //  File-scope or namespace-scope variables referenced in
>>>>>>>> called routines
>>>>>>>> +    //  in the region are shared unless they appear in a
>>>>>>>> threadprivate
>>>>>>>> +    //  directive.
>>>>>>>> +    // TODO
>>>>>>>> +    if (!D->isFunctionOrMethodVarDecl())
>>>>>>>> +      DVar.CKind = OMPC_shared;
>>>>>>>> +
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +  DVar.DKind = Iter->Directive;
>>>>>>>> +  // Explicitly specified attributes and local variables with
>>>>>>>> predetermined
>>>>>>>> +  // attributes.
>>>>>>>> +  if (Iter->SharingMap.count(D)) {
>>>>>>>> +    DVar.RefExpr = Iter->SharingMap[D].RefExpr;
>>>>>>>> +    DVar.CKind = Iter->SharingMap[D].Attributes;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, implicitly determined, p.1]
>>>>>>>> +  //  In a parallel or task construct, the data-sharing attributes
>>>>>>>> of these
>>>>>>>> +  //  variables are determined by the default clause, if present.
>>>>>>>> +  switch (Iter->DefaultAttr) {
>>>>>>>> +  case DSA_shared:
>>>>>>>> +    DVar.CKind = OMPC_shared;
>>>>>>>> +    return DVar;
>>>>>>>> +  case DSA_none:
>>>>>>>> +    return DVar;
>>>>>>>> +  case DSA_unspecified:
>>>>>>>> +    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +    // in a Construct, implicitly determined, p.2]
>>>>>>>> +    //  In a parallel construct, if no default clause is present,
>>>>>>>> these
>>>>>>>> +    //  variables are shared.
>>>>>>>> +    if (DVar.DKind == OMPD_parallel) {
>>>>>>>> +      DVar.CKind = OMPC_shared;
>>>>>>>> +      return DVar;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +    // in a Construct, implicitly determined, p.4]
>>>>>>>> +    //  In a task construct, if no default clause is present, a
>>>>>>>> variable that in
>>>>>>>> +    //  the enclosing context is determined to be shared by all
>>>>>>>> implicit tasks
>>>>>>>> +    //  bound to the current team is shared.
>>>>>>>> +    // TODO
>>>>>>>> +    if (DVar.DKind == OMPD_task) {
>>>>>>>> +      DSAVarData DVarTemp;
>>>>>>>> +      for (StackTy::reverse_iterator I = Iter + 1,
>>>>>>>> +                                     EE = Stack.rend() - 1;
>>>>>>>> +           I != EE; ++I) {
>>>>>>>> +        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for
>>>>>>>> Variables Referenced
>>>>>>>> +        // in a Construct, implicitly determined, p.6]
>>>>>>>> +        //  In a task construct, if no default clause is present,
>>>>>>>> a variable
>>>>>>>> +        //  whose data-sharing attribute is not determined by the
>>>>>>>> rules above is
>>>>>>>> +        //  firstprivate.
>>>>>>>> +        DVarTemp = getDSA(I, D);
>>>>>>>> +        if (DVarTemp.CKind != OMPC_shared) {
>>>>>>>> +          DVar.RefExpr = 0;
>>>>>>>> +          DVar.DKind = OMPD_task;
>>>>>>>> +          DVar.CKind = OMPC_unknown;
>>>>>>>> +          // TODO: should return OMPC_firstprivate
>>>>>>>> +          return DVar;
>>>>>>>> +        }
>>>>>>>> +        if (I->Directive == OMPD_parallel) break;
>>>>>>>> +      }
>>>>>>>> +      DVar.DKind = OMPD_task;
>>>>>>>> +      // TODO: Should return OMPC_firstprivate instead of
>>>>>>>> OMPC_unknown.
>>>>>>>> +      DVar.CKind =
>>>>>>>> +        (DVarTemp.CKind == OMPC_unknown) ? OMPC_unknown :
>>>>>>>> OMPC_shared;
>>>>>>>> +      return DVar;
>>>>>>>> +    }
>>>>>>>> +  }
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, implicitly determined, p.3]
>>>>>>>> +  //  For constructs other than task, if no default clause is
>>>>>>>> present, these
>>>>>>>> +  //  variables inherit their data-sharing attributes from the
>>>>>>>> enclosing
>>>>>>>> +  //  context.
>>>>>>>> +  return getDSA(Iter + 1, D);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E,
>>>>>>>> OpenMPClauseKind A) {
>>>>>>>> +  if (A == OMPC_threadprivate) {
>>>>>>>> +    Stack[0].SharingMap[D].Attributes = A;
>>>>>>>> +    Stack[0].SharingMap[D].RefExpr = E;
>>>>>>>> +  } else {
>>>>>>>> +    assert(Stack.size() > 1 && "Data-sharing attributes stack is
>>>>>>>> empty");
>>>>>>>> +    Stack.back().SharingMap[D].Attributes = A;
>>>>>>>> +    Stack.back().SharingMap[D].RefExpr = E;
>>>>>>>> +  }
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +bool DSAStackTy::isOpenMPLocal(VarDecl *D) {
>>>>>>>> +  Scope *CurScope = getCurScope();
>>>>>>>> +  while (CurScope && !CurScope->isDeclScope(D))
>>>>>>>> +    CurScope = CurScope->getParent();
>>>>>>>> +  while (CurScope && !CurScope->isOpenMPDirectiveScope())
>>>>>>>> +    CurScope = CurScope->getParent();
>>>>>>>> +  bool isOpenMPLocal = !!CurScope;
>>>>>>>> +  if (!isOpenMPLocal) {
>>>>>>>> +    CurScope = getCurScope();
>>>>>>>> +    while (CurScope && !CurScope->isOpenMPDirectiveScope())
>>>>>>>> +      CurScope = CurScope->getParent();
>>>>>>>> +    isOpenMPLocal =
>>>>>>>> +      CurScope &&
>>>>>>>> +      isa<CapturedDecl>(D->getDeclContext()) &&
>>>>>>>> +      static_cast<DeclContext *>(
>>>>>>>> +
>>>>>>>>  CurScope->getFnParent()->getEntity())->Encloses(D->getDeclContext());
>>>>>>>> +  }
>>>>>>>> +  return isOpenMPLocal;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D) {
>>>>>>>> +  DSAVarData DVar;
>>>>>>>> +
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, predetermined, p.1]
>>>>>>>> +  //  Variables appearing in threadprivate directives are
>>>>>>>> threadprivate.
>>>>>>>> +  if (D->getTLSKind() != VarDecl::TLS_None) {
>>>>>>>> +    DVar.CKind = OMPC_threadprivate;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +  if (Stack[0].SharingMap.count(D)) {
>>>>>>>> +    DVar.RefExpr = Stack[0].SharingMap[D].RefExpr;
>>>>>>>> +    DVar.CKind = OMPC_threadprivate;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, predetermined, p.1]
>>>>>>>> +  // Variables with automatic storage duration that are declared
>>>>>>>> in a scope
>>>>>>>> +  // inside the construct are private.
>>>>>>>> +  if (isOpenMPLocal(D) && D->isLocalVarDecl() &&
>>>>>>>> +      (D->getStorageClass() == SC_Auto ||
>>>>>>>> +       D->getStorageClass() == SC_None)) {
>>>>>>>> +    DVar.CKind = OMPC_private;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, predetermined, p.4]
>>>>>>>> +  //  Static data memebers are shared.
>>>>>>>> +  if (D->isStaticDataMember()) {
>>>>>>>> +    // Variables with const-qualified type having no mutable
>>>>>>>> member may be
>>>>>>>> +    // listed in a firstprivate clause, even if they are static
>>>>>>>> data members.
>>>>>>>> +    // TODO:
>>>>>>>> +    DVar.CKind = OMPC_shared;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  QualType Type =
>>>>>>>> D->getType().getNonReferenceType().getCanonicalType();
>>>>>>>> +  bool IsConstant = Type.isConstant(Actions.getASTContext());
>>>>>>>> +  while (Type->isArrayType()) {
>>>>>>>> +    QualType ElemType =
>>>>>>>> cast<ArrayType>(Type.getTypePtr())->getElementType();
>>>>>>>> +    Type = ElemType.getNonReferenceType().getCanonicalType();
>>>>>>>> +  }
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, predetermined, p.6]
>>>>>>>> +  //  Variables with const qualified type having no mutable member
>>>>>>>> are
>>>>>>>> +  //  shared.
>>>>>>>> +  CXXRecordDecl *RD = Actions.getLangOpts().CPlusPlus ?
>>>>>>>> +                                Type->getAsCXXRecordDecl() : 0;
>>>>>>>> +  if (IsConstant &&
>>>>>>>> +      !(Actions.getLangOpts().CPlusPlus && RD &&
>>>>>>>> RD->hasMutableFields())) {
>>>>>>>> +    // Variables with const-qualified type having no mutable
>>>>>>>> member may be
>>>>>>>> +    // listed in a firstprivate clause, even if they are static
>>>>>>>> data members.
>>>>>>>> +    // TODO
>>>>>>>> +    DVar.CKind = OMPC_shared;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +  // in a Construct, C/C++, predetermined, p.7]
>>>>>>>> +  //  Variables with static storage duration that are declared in
>>>>>>>> a scope
>>>>>>>> +  //  inside the construct are shared.
>>>>>>>> +  if (isOpenMPLocal(D) && D->isStaticLocal()) {
>>>>>>>> +    DVar.CKind = OMPC_shared;
>>>>>>>> +    return DVar;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  // Explicitly specified attributes and local variables with
>>>>>>>> predetermined
>>>>>>>> +  // attributes.
>>>>>>>> +  if (Stack.back().SharingMap.count(D)) {
>>>>>>>> +    DVar.RefExpr = Stack.back().SharingMap[D].RefExpr;
>>>>>>>> +    DVar.CKind = Stack.back().SharingMap[D].Attributes;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  return DVar;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D) {
>>>>>>>> +  return getDSA(Stack.rbegin() + 1, D);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +void Sema::InitDataSharingAttributesStack() {
>>>>>>>> +  VarDataSharingAttributesStack = new DSAStackTy(*this);
>>>>>>>>
>>>>>>>
>>>>>>> This is leaked, is that intentional?
>>>>>>>
>>>>>>
>>>>>> It's not leaked. The LSan failure that my magic 8-ball says you're
>>>>>> looking at stems from not deleting Sema.
>>>>>>
>>>>>
>>>>> Oh, you're right! The "define DSAStack" below confused my grepping.
>>>>>
>>>>> I think what's happening then is that the Sema object isn't Bury()d in
>>>>> the isCurrentFileAST() case. The attached patch fixes this. Does that look
>>>>> ok?
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>>  +}
>>>>>>>> +
>>>>>>>> +#define DSAStack static_cast<DSAStackTy
>>>>>>>> *>(VarDataSharingAttributesStack)
>>>>>>>> +
>>>>>>>> +void Sema::DestroyDataSharingAttributesStack() {
>>>>>>>> +  delete DSAStack;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
>>>>>>>> +                               const DeclarationNameInfo &DirName,
>>>>>>>> +                               Scope *CurScope) {
>>>>>>>> +  DSAStack->push(DKind, DirName, CurScope);
>>>>>>>> +  PushExpressionEvaluationContext(PotentiallyEvaluated);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
>>>>>>>> +  DSAStack->pop();
>>>>>>>> +  DiscardCleanupsInEvaluationContext();
>>>>>>>> +  PopExpressionEvaluationContext();
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  namespace {
>>>>>>>>
>>>>>>>>  class VarDeclFilterCCC : public CorrectionCandidateCallback {
>>>>>>>> @@ -130,6 +449,7 @@ ExprResult Sema::ActOnOpenMPIdExpression
>>>>>>>>
>>>>>>>>    QualType ExprType = VD->getType().getNonReferenceType();
>>>>>>>>    ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue,
>>>>>>>> Id.getLoc());
>>>>>>>> +  DSAStack->addDSA(VD, cast<DeclRefExpr>(DE.get()),
>>>>>>>> OMPC_threadprivate);
>>>>>>>>    return DE;
>>>>>>>>  }
>>>>>>>>
>>>>>>>> @@ -192,12 +512,93 @@ OMPThreadPrivateDecl *Sema::CheckOMPThre
>>>>>>>>                                                 Loc, Vars);
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +namespace {
>>>>>>>> +class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
>>>>>>>> +  DSAStackTy *Stack;
>>>>>>>> +  Sema &Actions;
>>>>>>>> +  bool ErrorFound;
>>>>>>>> +  CapturedStmt *CS;
>>>>>>>> +public:
>>>>>>>> +  void VisitDeclRefExpr(DeclRefExpr *E) {
>>>>>>>> +    if(VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
>>>>>>>> +      if (VD->isImplicit() && VD->hasAttr<UnusedAttr>()) return;
>>>>>>>> +      // Skip internally declared variables.
>>>>>>>> +      if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
>>>>>>>> return;
>>>>>>>> +
>>>>>>>> +      SourceLocation ELoc = E->getExprLoc();
>>>>>>>> +
>>>>>>>> +      OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
>>>>>>>> +      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
>>>>>>>> +      if (DVar.CKind != OMPC_unknown) {
>>>>>>>> +        if (DKind == OMPD_task && DVar.CKind != OMPC_shared &&
>>>>>>>> +            DVar.CKind != OMPC_threadprivate && !DVar.RefExpr)
>>>>>>>> +          // TODO: should be marked as firstprivate.
>>>>>>>> +          ;
>>>>>>>> +        return;
>>>>>>>> +      }
>>>>>>>> +      // The default(none) clause requires that each variable that
>>>>>>>> is referenced
>>>>>>>> +      // in the construct, and does not have a predetermined
>>>>>>>> data-sharing
>>>>>>>> +      // attribute, must have its data-sharing attribute
>>>>>>>> explicitly determined
>>>>>>>> +      // by being listed in a data-sharing attribute clause.
>>>>>>>> +      if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() ==
>>>>>>>> DSA_none &&
>>>>>>>> +          (DKind == OMPD_parallel || DKind == OMPD_task)) {
>>>>>>>> +        ErrorFound = true;
>>>>>>>> +        Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) <<
>>>>>>>> VD;
>>>>>>>> +        return;
>>>>>>>> +      }
>>>>>>>> +
>>>>>>>> +      // OpenMP [2.9.3.6, Restrictions, p.2]
>>>>>>>> +      //  A list item that appears in a reduction clause of the
>>>>>>>> innermost
>>>>>>>> +      //  enclosing worksharing or parallel construct may not be
>>>>>>>> accessed in an
>>>>>>>> +      //  explicit task.
>>>>>>>> +      // TODO:
>>>>>>>> +
>>>>>>>> +      // Define implicit data-sharing attributes for task.
>>>>>>>> +      DVar = Stack->getImplicitDSA(VD);
>>>>>>>> +      if (DKind == OMPD_task && DVar.CKind != OMPC_shared) {
>>>>>>>> +        // TODO: should be marked as firstprivate.
>>>>>>>> +      }
>>>>>>>> +    }
>>>>>>>> +  }
>>>>>>>> +  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
>>>>>>>> +    for (ArrayRef<OMPClause *>::iterator I = S->clauses().begin(),
>>>>>>>> +                                         E = S->clauses().end();
>>>>>>>> +         I != E; ++I)
>>>>>>>> +      if (OMPClause *C = *I)
>>>>>>>> +        for (StmtRange R = C->children(); R; ++R)
>>>>>>>> +          if (Stmt *Child = *R)
>>>>>>>> +            Visit(Child);
>>>>>>>> +  }
>>>>>>>> +  void VisitStmt(Stmt *S) {
>>>>>>>> +    for (Stmt::child_iterator I = S->child_begin(), E =
>>>>>>>> S->child_end();
>>>>>>>> +         I != E; ++I)
>>>>>>>> +      if (Stmt *Child = *I)
>>>>>>>> +        if (!isa<OMPExecutableDirective>(Child))
>>>>>>>> +          Visit(Child);
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +  bool isErrorFound() { return ErrorFound; }
>>>>>>>> +
>>>>>>>> +  DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
>>>>>>>> +    : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) { }
>>>>>>>> +};
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  StmtResult
>>>>>>>> Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
>>>>>>>>                                                  ArrayRef<OMPClause
>>>>>>>> *> Clauses,
>>>>>>>>                                                  Stmt *AStmt,
>>>>>>>>                                                  SourceLocation
>>>>>>>> StartLoc,
>>>>>>>>                                                  SourceLocation
>>>>>>>> EndLoc) {
>>>>>>>> +  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement
>>>>>>>> expected");
>>>>>>>> +
>>>>>>>>    StmtResult Res = StmtError();
>>>>>>>> +
>>>>>>>> +  // Check default data sharing attributes for referenced
>>>>>>>> variables.
>>>>>>>> +  DSAAttrChecker DSAChecker(DSAStack, *this,
>>>>>>>> cast<CapturedStmt>(AStmt));
>>>>>>>> +  DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
>>>>>>>> +  if (DSAChecker.isErrorFound())
>>>>>>>> +    return StmtError();
>>>>>>>> +
>>>>>>>>    switch (Kind) {
>>>>>>>>    case OMPD_parallel:
>>>>>>>>      Res = ActOnOpenMPParallelDirective(Clauses, AStmt, StartLoc,
>>>>>>>> EndLoc);
>>>>>>>> @@ -231,11 +632,12 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
>>>>>>>>    OMPClause *Res = 0;
>>>>>>>>    switch (Kind) {
>>>>>>>>    case OMPC_default:
>>>>>>>> -    Res = ActOnOpenMPDefaultClause(
>>>>>>>> -
>>>>>>>> static_cast<OpenMPDefaultClauseKind>(Argument),
>>>>>>>> -                             ArgumentLoc, StartLoc, LParenLoc,
>>>>>>>> EndLoc);
>>>>>>>> +    Res =
>>>>>>>> +
>>>>>>>>  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
>>>>>>>> +                               ArgumentLoc, StartLoc, LParenLoc,
>>>>>>>> EndLoc);
>>>>>>>>      break;
>>>>>>>>    case OMPC_private:
>>>>>>>> +  case OMPC_shared:
>>>>>>>>    case OMPC_threadprivate:
>>>>>>>>    case OMPC_unknown:
>>>>>>>>    case NUM_OPENMP_CLAUSES:
>>>>>>>> @@ -272,6 +674,16 @@ OMPClause *Sema::ActOnOpenMPDefaultClaus
>>>>>>>>        << Values << getOpenMPClauseName(OMPC_default);
>>>>>>>>      return 0;
>>>>>>>>    }
>>>>>>>> +  switch (Kind) {
>>>>>>>> +  case OMPC_DEFAULT_none:
>>>>>>>> +    DSAStack->setDefaultDSANone();
>>>>>>>> +    break;
>>>>>>>> +  case OMPC_DEFAULT_shared:
>>>>>>>> +    DSAStack->setDefaultDSAShared();
>>>>>>>> +    break;
>>>>>>>> +  default:
>>>>>>>> +    break;
>>>>>>>> +  }
>>>>>>>>    return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc,
>>>>>>>> LParenLoc,
>>>>>>>>                                          EndLoc);
>>>>>>>>  }
>>>>>>>> @@ -286,6 +698,9 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
>>>>>>>>    case OMPC_private:
>>>>>>>>      Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
>>>>>>>> EndLoc);
>>>>>>>>      break;
>>>>>>>> +  case OMPC_shared:
>>>>>>>> +    Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
>>>>>>>> EndLoc);
>>>>>>>> +    break;
>>>>>>>>    case OMPC_default:
>>>>>>>>    case OMPC_threadprivate:
>>>>>>>>    case OMPC_unknown:
>>>>>>>> @@ -396,6 +811,29 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus
>>>>>>>>        }
>>>>>>>>      }
>>>>>>>>
>>>>>>>> +    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +    // in a Construct]
>>>>>>>> +    //  Variables with the predetermined data-sharing attributes
>>>>>>>> may not be
>>>>>>>> +    //  listed in data-sharing attributes clauses, except for the
>>>>>>>> cases
>>>>>>>> +    //  listed below. For these exceptions only, listing a
>>>>>>>> predetermined
>>>>>>>> +    //  variable in a data-sharing attribute clause is allowed and
>>>>>>>> overrides
>>>>>>>> +    //  the variable's predetermined data-sharing attributes.
>>>>>>>> +    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
>>>>>>>> +    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
>>>>>>>> +      Diag(ELoc, diag::err_omp_wrong_dsa)
>>>>>>>> +         << getOpenMPClauseName(DVar.CKind)
>>>>>>>> +         << getOpenMPClauseName(OMPC_private);
>>>>>>>> +      if (DVar.RefExpr) {
>>>>>>>> +        Diag(DVar.RefExpr->getExprLoc(),
>>>>>>>> diag::note_omp_explicit_dsa)
>>>>>>>> +             << getOpenMPClauseName(DVar.CKind);
>>>>>>>> +      } else {
>>>>>>>> +        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
>>>>>>>> +             << getOpenMPClauseName(DVar.CKind);
>>>>>>>> +      }
>>>>>>>> +      continue;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    DSAStack->addDSA(VD, DE, OMPC_private);
>>>>>>>>      Vars.push_back(DE);
>>>>>>>>    }
>>>>>>>>
>>>>>>>> @@ -404,3 +842,65 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus
>>>>>>>>    return OMPPrivateClause::Create(Context, StartLoc, LParenLoc,
>>>>>>>> EndLoc, Vars);
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
>>>>>>>> +                                         SourceLocation StartLoc,
>>>>>>>> +                                         SourceLocation LParenLoc,
>>>>>>>> +                                         SourceLocation EndLoc) {
>>>>>>>> +  SmallVector<Expr *, 8> Vars;
>>>>>>>> +  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E =
>>>>>>>> VarList.end();
>>>>>>>> +       I != E; ++I) {
>>>>>>>> +    if (*I && isa<DependentScopeDeclRefExpr>(*I)) {
>>>>>>>> +      // It will be analyzed later.
>>>>>>>> +      Vars.push_back(*I);
>>>>>>>> +      continue;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    SourceLocation ELoc = (*I)->getExprLoc();
>>>>>>>> +    // OpenMP [2.1, C/C++]
>>>>>>>> +    //  A list item is a variable name.
>>>>>>>> +    // OpenMP  [2.9.3.4, Restrictions, p.1]
>>>>>>>> +    //  A variable that is part of another variable (as an array or
>>>>>>>> +    //  structure element) cannot appear in a private clause.
>>>>>>>> +    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
>>>>>>>> +    if (!DE || !isa<VarDecl>(DE->getDecl())) {
>>>>>>>> +      Diag(ELoc, diag::err_omp_expected_var_name)
>>>>>>>> +        << (*I)->getSourceRange();
>>>>>>>> +      continue;
>>>>>>>> +    }
>>>>>>>> +    Decl *D = DE->getDecl();
>>>>>>>> +    VarDecl *VD = cast<VarDecl>(D);
>>>>>>>> +
>>>>>>>> +    QualType Type = VD->getType();
>>>>>>>> +    if (Type->isDependentType() ||
>>>>>>>> Type->isInstantiationDependentType()) {
>>>>>>>> +      // It will be analyzed later.
>>>>>>>> +      Vars.push_back(DE);
>>>>>>>> +      continue;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
>>>>>>>> Referenced
>>>>>>>> +    // in a Construct]
>>>>>>>> +    //  Variables with the predetermined data-sharing attributes
>>>>>>>> may not be
>>>>>>>> +    //  listed in data-sharing attributes clauses, except for the
>>>>>>>> cases
>>>>>>>> +    //  listed below. For these exceptions only, listing a
>>>>>>>> predetermined
>>>>>>>> +    //  variable in a data-sharing attribute clause is allowed and
>>>>>>>> overrides
>>>>>>>> +    //  the variable's predetermined data-sharing attributes.
>>>>>>>> +    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
>>>>>>>> +    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
>>>>>>>> DVar.RefExpr) {
>>>>>>>> +      Diag(ELoc, diag::err_omp_wrong_dsa)
>>>>>>>> +         << getOpenMPClauseName(DVar.CKind)
>>>>>>>> +         << getOpenMPClauseName(OMPC_shared);
>>>>>>>> +      Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
>>>>>>>> +           << getOpenMPClauseName(DVar.CKind);
>>>>>>>> +      continue;
>>>>>>>> +    }
>>>>>>>> +
>>>>>>>> +    DSAStack->addDSA(VD, DE, OMPC_shared);
>>>>>>>> +    Vars.push_back(DE);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  if (Vars.empty()) return 0;
>>>>>>>> +
>>>>>>>> +  return OMPSharedClause::Create(Context, StartLoc, LParenLoc,
>>>>>>>> EndLoc, Vars);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +#undef DSAStack
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>>>>>>>> +++ cfe/trunk/lib/Sema/TreeTransform.h Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -1312,6 +1312,14 @@ public:
>>>>>>>>                                                EndLoc);
>>>>>>>>    }
>>>>>>>>
>>>>>>>> +  OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
>>>>>>>> +                                    SourceLocation StartLoc,
>>>>>>>> +                                    SourceLocation LParenLoc,
>>>>>>>> +                                    SourceLocation EndLoc) {
>>>>>>>> +    return getSema().ActOnOpenMPSharedClause(VarList, StartLoc,
>>>>>>>> LParenLoc,
>>>>>>>> +                                             EndLoc);
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>>    /// \brief Rebuild the operand to an Objective-C \@synchronized
>>>>>>>> statement.
>>>>>>>>    ///
>>>>>>>>    /// By default, performs semantic analysis to build the new
>>>>>>>> statement.
>>>>>>>> @@ -6254,33 +6262,44 @@ TreeTransform<Derived>::TransformSEHHand
>>>>>>>>  template<typename Derived>
>>>>>>>>  StmtResult
>>>>>>>>  TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective
>>>>>>>> *D) {
>>>>>>>> +  DeclarationNameInfo DirName;
>>>>>>>> +  getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, 0);
>>>>>>>> +
>>>>>>>>    // Transform the clauses
>>>>>>>> -  SmallVector<OMPClause *, 5> TClauses;
>>>>>>>> +  llvm::SmallVector<OMPClause *, 16> TClauses;
>>>>>>>>    ArrayRef<OMPClause *> Clauses = D->clauses();
>>>>>>>>    TClauses.reserve(Clauses.size());
>>>>>>>>    for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E =
>>>>>>>> Clauses.end();
>>>>>>>>         I != E; ++I) {
>>>>>>>>      if (*I) {
>>>>>>>>        OMPClause *Clause = getDerived().TransformOMPClause(*I);
>>>>>>>> -      if (!Clause)
>>>>>>>> +      if (!Clause) {
>>>>>>>> +        getSema().EndOpenMPDSABlock(0);
>>>>>>>>          return StmtError();
>>>>>>>> +      }
>>>>>>>>        TClauses.push_back(Clause);
>>>>>>>>      }
>>>>>>>>      else {
>>>>>>>>        TClauses.push_back(0);
>>>>>>>>      }
>>>>>>>>    }
>>>>>>>> -  if (!D->getAssociatedStmt())
>>>>>>>> +  if (!D->getAssociatedStmt()) {
>>>>>>>> +    getSema().EndOpenMPDSABlock(0);
>>>>>>>>      return StmtError();
>>>>>>>> +  }
>>>>>>>>    StmtResult AssociatedStmt =
>>>>>>>>      getDerived().TransformStmt(D->getAssociatedStmt());
>>>>>>>> -  if (AssociatedStmt.isInvalid())
>>>>>>>> +  if (AssociatedStmt.isInvalid()) {
>>>>>>>> +    getSema().EndOpenMPDSABlock(0);
>>>>>>>>      return StmtError();
>>>>>>>> +  }
>>>>>>>>
>>>>>>>> -  return getDerived().RebuildOMPParallelDirective(TClauses,
>>>>>>>> -
>>>>>>>>  AssociatedStmt.take(),
>>>>>>>> -                                                  D->getLocStart(),
>>>>>>>> -                                                  D->getLocEnd());
>>>>>>>> +  StmtResult Res =
>>>>>>>> getDerived().RebuildOMPParallelDirective(TClauses,
>>>>>>>> +
>>>>>>>>  AssociatedStmt.take(),
>>>>>>>> +
>>>>>>>>  D->getLocStart(),
>>>>>>>> +
>>>>>>>>  D->getLocEnd());
>>>>>>>> +  getSema().EndOpenMPDSABlock(Res.get());
>>>>>>>> +  return Res;
>>>>>>>>  }
>>>>>>>>
>>>>>>>>  template<typename Derived>
>>>>>>>> @@ -6296,7 +6315,7 @@ TreeTransform<Derived>::TransformOMPDefa
>>>>>>>>  template<typename Derived>
>>>>>>>>  OMPClause *
>>>>>>>>  TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause
>>>>>>>> *C) {
>>>>>>>> -  SmallVector<Expr *, 5> Vars;
>>>>>>>> +  llvm::SmallVector<Expr *, 16> Vars;
>>>>>>>>    Vars.reserve(C->varlist_size());
>>>>>>>>    for (OMPVarList<OMPPrivateClause>::varlist_iterator I =
>>>>>>>> C->varlist_begin(),
>>>>>>>>                                                        E =
>>>>>>>> C->varlist_end();
>>>>>>>> @@ -6312,6 +6331,25 @@ TreeTransform<Derived>::TransformOMPPriv
>>>>>>>>                                                C->getLocEnd());
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +template<typename Derived>
>>>>>>>> +OMPClause *
>>>>>>>> +TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause
>>>>>>>> *C) {
>>>>>>>> +  llvm::SmallVector<Expr *, 16> Vars;
>>>>>>>> +  Vars.reserve(C->varlist_size());
>>>>>>>> +  for (OMPVarList<OMPSharedClause>::varlist_iterator I =
>>>>>>>> C->varlist_begin(),
>>>>>>>> +                                                     E =
>>>>>>>> C->varlist_end();
>>>>>>>> +       I != E; ++I) {
>>>>>>>> +    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
>>>>>>>> +    if (EVar.isInvalid())
>>>>>>>> +      return 0;
>>>>>>>> +    Vars.push_back(EVar.take());
>>>>>>>> +  }
>>>>>>>> +  return getDerived().RebuildOMPSharedClause(Vars,
>>>>>>>> +                                             C->getLocStart(),
>>>>>>>> +                                             C->getLParenLoc(),
>>>>>>>> +                                             C->getLocEnd());
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>  // Expression transformation
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -1689,6 +1689,9 @@ OMPClause *OMPClauseReader::readClause()
>>>>>>>>    case OMPC_private:
>>>>>>>>      C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
>>>>>>>>      break;
>>>>>>>> +  case OMPC_shared:
>>>>>>>> +    C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
>>>>>>>> +    break;
>>>>>>>>    }
>>>>>>>>    Visit(C);
>>>>>>>>    C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
>>>>>>>> @@ -1708,6 +1711,16 @@ void OMPClauseReader::VisitOMPPrivateCla
>>>>>>>>    C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
>>>>>>>>    unsigned NumVars = C->varlist_size();
>>>>>>>>    SmallVector<Expr *, 16> Vars;
>>>>>>>> +  Vars.reserve(NumVars);
>>>>>>>> +  for (unsigned i = 0; i != NumVars; ++i)
>>>>>>>> +    Vars.push_back(Reader->Reader.ReadSubExpr());
>>>>>>>> +  C->setVarRefs(Vars);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
>>>>>>>> +  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
>>>>>>>> +  unsigned NumVars = C->varlist_size();
>>>>>>>> +  SmallVector<Expr *, 16> Vars;
>>>>>>>>    Vars.reserve(NumVars);
>>>>>>>>    for (unsigned i = 0; i != NumVars; ++i)
>>>>>>>>      Vars.push_back(Reader->Reader.ReadSubExpr());
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
>>>>>>>> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -1703,6 +1703,15 @@ void OMPClauseWriter::VisitOMPPrivateCla
>>>>>>>>      Writer->Writer.AddStmt(*I);
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
>>>>>>>> +  Record.push_back(C->varlist_size());
>>>>>>>> +  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
>>>>>>>> +  for (OMPVarList<OMPSharedClause>::varlist_iterator I =
>>>>>>>> C->varlist_begin(),
>>>>>>>> +                                                     E =
>>>>>>>> C->varlist_end();
>>>>>>>> +       I != E; ++I)
>>>>>>>> +    Writer->Writer.AddStmt(*I);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>  // OpenMP Directives.
>>>>>>>>
>>>>>>>>  //===----------------------------------------------------------------------===//
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/test/OpenMP/openmp_common.c
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/openmp_common.c?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/test/OpenMP/openmp_common.c (original)
>>>>>>>> +++ cfe/trunk/test/OpenMP/openmp_common.c Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -1,4 +1,4 @@
>>>>>>>> -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify
>>>>>>>> -fopenmp -ferror-limit 100 -o - %s
>>>>>>>> +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
>>>>>>>>
>>>>>>>>  #pragma omp // expected-error {{expected an OpenMP directive}}
>>>>>>>>  #pragma omp unknown_directive // expected-error {{expected an
>>>>>>>> OpenMP directive}}
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/test/OpenMP/parallel_default_messages.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_default_messages.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/test/OpenMP/parallel_default_messages.cpp (original)
>>>>>>>> +++ cfe/trunk/test/OpenMP/parallel_default_messages.cpp Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -1,4 +1,4 @@
>>>>>>>> -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify
>>>>>>>> -fopenmp -ferror-limit 100 -o - %s
>>>>>>>> +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
>>>>>>>>
>>>>>>>>  void foo();
>>>>>>>>
>>>>>>>> @@ -11,5 +11,11 @@ int main(int argc, char **argv) {
>>>>>>>>    #pragma omp parallel default (x) // expected-error {{expected
>>>>>>>> 'none' or 'shared' in OpenMP clause 'default'}}
>>>>>>>>    foo();
>>>>>>>>
>>>>>>>> +  #pragma omp parallel default(none)
>>>>>>>> +  ++argc; // expected-error {{variable 'argc' must have explicitly
>>>>>>>> specified data sharing attributes}}
>>>>>>>> +
>>>>>>>> +  #pragma omp parallel default(none)
>>>>>>>> +  #pragma omp parallel default(shared)
>>>>>>>> +  ++argc;
>>>>>>>>    return 0;
>>>>>>>>  }
>>>>>>>>
>>>>>>>> Added: cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_messages.cpp?rev=190183&view=auto
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/test/OpenMP/parallel_messages.cpp (added)
>>>>>>>> +++ cfe/trunk/test/OpenMP/parallel_messages.cpp Fri Sep  6 13:03:48
>>>>>>>> 2013
>>>>>>>> @@ -0,0 +1,49 @@
>>>>>>>> +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
>>>>>>>> +
>>>>>>>> +void foo() {
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +#pragma omp parallel // expected-error {{unexpected OpenMP
>>>>>>>> directive '#pragma omp parallel'}}
>>>>>>>> +
>>>>>>>> +int main(int argc, char **argv) {
>>>>>>>> +  #pragma omp parallel
>>>>>>>> +  #pragma omp parallel unknown() // expected-warning {{extra
>>>>>>>> tokens at the end of '#pragma omp parallel' are ignored}}
>>>>>>>> +  foo();
>>>>>>>> +  L1:
>>>>>>>> +    foo();
>>>>>>>> +  #pragma omp parallel
>>>>>>>> +  ;
>>>>>>>> +  #pragma omp parallel
>>>>>>>> +  {
>>>>>>>> +    goto L1; // expected-error {{use of undeclared label 'L1'}}
>>>>>>>> +    argc++;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  for (int i = 0; i < 10; ++i) {
>>>>>>>> +    switch(argc) {
>>>>>>>> +     case (0):
>>>>>>>> +      #pragma omp parallel
>>>>>>>> +      {
>>>>>>>> +        foo();
>>>>>>>> +        break; // expected-error {{'break' statement not in loop
>>>>>>>> or switch statement}}
>>>>>>>> +        continue; // expected-error {{'continue' statement not in
>>>>>>>> loop statement}}
>>>>>>>> +      }
>>>>>>>> +      default:
>>>>>>>> +       break;
>>>>>>>> +    }
>>>>>>>> +  }
>>>>>>>> +  #pragma omp parallel default(none)
>>>>>>>> +  ++argc; // expected-error {{variable 'argc' must have explicitly
>>>>>>>> specified data sharing attributes}}
>>>>>>>> +
>>>>>>>> +  goto L2; // expected-error {{use of undeclared label 'L2'}}
>>>>>>>> +  #pragma omp parallel
>>>>>>>> +  L2:
>>>>>>>> +  foo();
>>>>>>>> +  #pragma omp parallel
>>>>>>>> +  {
>>>>>>>> +    return 1; // expected-error {{cannot return from OpenMP
>>>>>>>> region}}
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:eol-style = native
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:keywords = Author Date Id Rev URL
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:mime-type = text/plain
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/test/OpenMP/parallel_private_messages.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_messages.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/test/OpenMP/parallel_private_messages.cpp (original)
>>>>>>>> +++ cfe/trunk/test/OpenMP/parallel_private_messages.cpp Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -1,4 +1,4 @@
>>>>>>>> -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify
>>>>>>>> -fopenmp -ferror-limit 100 %s
>>>>>>>> +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
>>>>>>>>
>>>>>>>>  void foo() {
>>>>>>>>  }
>>>>>>>> @@ -13,7 +13,7 @@ class S2 {
>>>>>>>>    mutable int a;
>>>>>>>>  public:
>>>>>>>>    S2():a(0) { }
>>>>>>>> -  static float S2s;
>>>>>>>> +  static float S2s; // expected-note {{predetermined as shared}}
>>>>>>>>  };
>>>>>>>>  const S2 b;
>>>>>>>>  const S2 ba[5];
>>>>>>>> @@ -22,9 +22,9 @@ class S3 {
>>>>>>>>  public:
>>>>>>>>    S3():a(0) { }
>>>>>>>>  };
>>>>>>>> -const S3 c;
>>>>>>>> -const S3 ca[5];
>>>>>>>> -extern const int f;
>>>>>>>> +const S3 c; // expected-note {{predetermined as shared}}
>>>>>>>> +const S3 ca[5]; // expected-note {{predetermined as shared}}
>>>>>>>> +extern const int f; // expected-note {{predetermined as shared}}
>>>>>>>>  class S4 { // expected-note {{'S4' declared here}}
>>>>>>>>    int a;
>>>>>>>>    S4();
>>>>>>>> @@ -38,9 +38,12 @@ public:
>>>>>>>>    S5(int v):a(v) { }
>>>>>>>>  };
>>>>>>>>
>>>>>>>> +int threadvar;
>>>>>>>> +#pragma omp threadprivate(threadvar) // expected-note {{defined as
>>>>>>>> threadprivate or thread local}}
>>>>>>>> +
>>>>>>>>  int main(int argc, char **argv) {
>>>>>>>> -  const int d = 5;
>>>>>>>> -  const int da[5] = { 0 };
>>>>>>>> +  const int d = 5; // expected-note {{predetermined as shared}}
>>>>>>>> +  const int da[5] = { 0 }; // expected-note {{predetermined as
>>>>>>>> shared}}
>>>>>>>>    S4 e(4); // expected-note {{'e' defined here}}
>>>>>>>>    S5 g(5); // expected-note {{'g' defined here}}
>>>>>>>>    int i;
>>>>>>>> @@ -53,13 +56,14 @@ int main(int argc, char **argv) {
>>>>>>>>    #pragma omp parallel private (argc > 0 ? argv[1] : argv[2]) //
>>>>>>>> expected-error {{expected variable name}}
>>>>>>>>    #pragma omp parallel private (argc argv) // expected-error
>>>>>>>> {{expected ',' or ')' in 'private' clause}}
>>>>>>>>    #pragma omp parallel private (S1) // expected-error {{'S1' does
>>>>>>>> not refer to a value}}
>>>>>>>> -  #pragma omp parallel private (a, b, c, d, f) // expected-error
>>>>>>>> {{a private variable with incomplete type 'S1'}}
>>>>>>>> +  #pragma omp parallel private (a, b, c, d, f) // expected-error
>>>>>>>> {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared
>>>>>>>> variable cannot be private}}
>>>>>>>>    #pragma omp parallel private (argv[1]) // expected-error
>>>>>>>> {{expected variable name}}
>>>>>>>>    #pragma omp parallel private(ba)
>>>>>>>> -  #pragma omp parallel private(ca)
>>>>>>>> -  #pragma omp parallel private(da)
>>>>>>>> -  #pragma omp parallel private(S2::S2s)
>>>>>>>> +  #pragma omp parallel private(ca) // expected-error {{shared
>>>>>>>> variable cannot be private}}
>>>>>>>> +  #pragma omp parallel private(da) // expected-error {{shared
>>>>>>>> variable cannot be private}}
>>>>>>>> +  #pragma omp parallel private(S2::S2s) // expected-error {{shared
>>>>>>>> variable cannot be private}}
>>>>>>>>    #pragma omp parallel private(e, g) // expected-error 2 {{private
>>>>>>>> variable must have an accessible, unambiguous default constructor}}
>>>>>>>> +  #pragma omp parallel private(threadvar) // expected-error
>>>>>>>> {{threadprivate or thread local variable cannot be private}}
>>>>>>>>    foo();
>>>>>>>>    #pragma omp parallel private(i)
>>>>>>>>    #pragma omp parallel private(j) // expected-error {{arguments of
>>>>>>>> OpenMP clause 'private' cannot be of reference type 'int &'}}
>>>>>>>>
>>>>>>>> Added: cfe/trunk/test/OpenMP/parallel_shared_messages.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_shared_messages.cpp?rev=190183&view=auto
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/test/OpenMP/parallel_shared_messages.cpp (added)
>>>>>>>> +++ cfe/trunk/test/OpenMP/parallel_shared_messages.cpp Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -0,0 +1,77 @@
>>>>>>>> +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
>>>>>>>> +
>>>>>>>> +void foo() {
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +bool foobool(int argc) {
>>>>>>>> +  return argc;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +struct S1; // expected-note {{declared here}}
>>>>>>>> +extern S1 a;
>>>>>>>> +class S2 {
>>>>>>>> +  mutable int a;
>>>>>>>> +public:
>>>>>>>> +  S2():a(0) { }
>>>>>>>> +  S2(S2 &s2):a(s2.a) { }
>>>>>>>> +};
>>>>>>>> +const S2 b;
>>>>>>>> +const S2 ba[5];
>>>>>>>> +class S3 {
>>>>>>>> +  int a;
>>>>>>>> +public:
>>>>>>>> +  S3():a(0) { }
>>>>>>>> +  S3(S3 &s3):a(s3.a) { }
>>>>>>>> +};
>>>>>>>> +const S3 c;
>>>>>>>> +const S3 ca[5];
>>>>>>>> +extern const int f;
>>>>>>>> +class S4 {
>>>>>>>> +  int a;
>>>>>>>> +  S4();
>>>>>>>> +  S4(const S4 &s4);
>>>>>>>> +public:
>>>>>>>> +  S4(int v):a(v) { }
>>>>>>>> +};
>>>>>>>> +class S5 {
>>>>>>>> +  int a;
>>>>>>>> +  S5():a(0) {}
>>>>>>>> +  S5(const S5 &s5):a(s5.a) { }
>>>>>>>> +public:
>>>>>>>> +  S5(int v):a(v) { }
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +S3 h;
>>>>>>>> +#pragma omp threadprivate(h) // expected-note {{defined as
>>>>>>>> threadprivate or thread local}}
>>>>>>>> +
>>>>>>>> +int main(int argc, char **argv) {
>>>>>>>> +  const int d = 5;
>>>>>>>> +  const int da[5] = { 0 };
>>>>>>>> +  S4 e(4);
>>>>>>>> +  S5 g(5);
>>>>>>>> +  int i;
>>>>>>>> +  int &j = i;
>>>>>>>> +  #pragma omp parallel shared // expected-error {{expected '('
>>>>>>>> after 'shared'}}
>>>>>>>> +  #pragma omp parallel shared ( // expected-error {{expected
>>>>>>>> expression}} expected-error {{expected ')'}} expected-note {{to match this
>>>>>>>> '('}}
>>>>>>>> +  #pragma omp parallel shared () // expected-error {{expected
>>>>>>>> expression}}
>>>>>>>> +  #pragma omp parallel shared (argc // expected-error {{expected
>>>>>>>> ')'}} expected-note {{to match this '('}}
>>>>>>>> +  #pragma omp parallel shared (argc, // expected-error {{expected
>>>>>>>> expression}} expected-error {{expected ')'}} expected-note {{to match this
>>>>>>>> '('}}
>>>>>>>> +  #pragma omp parallel shared (argc > 0 ? argv[1] : argv[2]) //
>>>>>>>> expected-error {{expected variable name}}
>>>>>>>> +  #pragma omp parallel shared (argc)
>>>>>>>> +  #pragma omp parallel shared (S1) // expected-error {{'S1' does
>>>>>>>> not refer to a value}}
>>>>>>>> +  #pragma omp parallel shared (a, b, c, d, f)
>>>>>>>> +  #pragma omp parallel shared (argv[1]) // expected-error
>>>>>>>> {{expected variable name}}
>>>>>>>> +  #pragma omp parallel shared(ba)
>>>>>>>> +  #pragma omp parallel shared(ca)
>>>>>>>> +  #pragma omp parallel shared(da)
>>>>>>>> +  #pragma omp parallel shared(e, g)
>>>>>>>> +  #pragma omp parallel shared(h) // expected-error {{threadprivate
>>>>>>>> or thread local variable cannot be shared}}
>>>>>>>> +  #pragma omp parallel private(i), shared(i) // expected-error
>>>>>>>> {{private variable cannot be shared}} expected-note {{defined as private}}
>>>>>>>> +  foo();
>>>>>>>> +  #pragma omp parallel private(i)
>>>>>>>> +  #pragma omp parallel shared(i)
>>>>>>>> +  #pragma omp parallel shared(j)
>>>>>>>> +  foo();
>>>>>>>> +
>>>>>>>> +  return 0;
>>>>>>>> +}
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_shared_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:eol-style = native
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_shared_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:keywords = Author Date Id Rev URL
>>>>>>>>
>>>>>>>> Propchange: cfe/trunk/test/OpenMP/parallel_shared_messages.cpp
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>     svn:mime-type = text/plain
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/tools/libclang/CIndex.cpp
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
>>>>>>>> +++ cfe/trunk/tools/libclang/CIndex.cpp Fri Sep  6 13:03:48 2013
>>>>>>>> @@ -1936,6 +1936,9 @@ void OMPClauseEnqueue::VisitOMPDefaultCl
>>>>>>>>  void OMPClauseEnqueue::VisitOMPPrivateClause(const
>>>>>>>> OMPPrivateClause *C) {
>>>>>>>>    PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
>>>>>>>>  }
>>>>>>>> +void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause
>>>>>>>> *C) {
>>>>>>>> +  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
>>>>>>>> +}
>>>>>>>>  #undef PROCESS_OMP_CLAUSE_LIST
>>>>>>>>  }
>>>>>>>>  void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
>>>>>>>>
>>>>>>>> Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h
>>>>>>>> URL:
>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=190183&r1=190182&r2=190183&view=diff
>>>>>>>>
>>>>>>>> ==============================================================================
>>>>>>>> --- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original)
>>>>>>>> +++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Fri Sep  6
>>>>>>>> 13:03:48 2013
>>>>>>>> @@ -2337,6 +2337,12 @@ bool RecursiveASTVisitor<Derived>::Visit
>>>>>>>>    return true;
>>>>>>>>  }
>>>>>>>>
>>>>>>>> +template<typename Derived>
>>>>>>>> +bool
>>>>>>>> RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
>>>>>>>> +  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
>>>>>>>> +  return true;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  #undef PROCESS_OMP_CLAUSE_LIST
>>>>>>>>
>>>>>>>>  // FIXME: look at the following tricky-seeming exprs to see if we
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> cfe-commits mailing list
>>>>>>>> cfe-commits at cs.uiuc.edu
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> cfe-commits mailing list
>>>>>>> cfe-commits at cs.uiuc.edu
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140423/a8ffc631/attachment.html>
-------------- next part --------------
Index: lib/Frontend/FrontendAction.cpp
===================================================================
--- lib/Frontend/FrontendAction.cpp	(revision 207056)
+++ lib/Frontend/FrontendAction.cpp	(working copy)
@@ -408,16 +408,16 @@
   // Finalize the action.
   EndSourceFileAction();
 
-  // Release the consumer and the AST, in that order since the consumer may
-  // perform actions in its destructor which require the context.
+  // Sema references the ast consumer, so reset sema first.
   //
   // FIXME: There is more per-file stuff we could just drop here?
-  if (CI.getFrontendOpts().DisableFree) {
-    BuryPointer(CI.takeASTConsumer());
+  bool DisableFree = CI.getFrontendOpts().DisableFree;
+  if (DisableFree) {
     if (!isCurrentFileAST()) {
       CI.resetAndLeakSema();
       CI.resetAndLeakASTContext();
     }
+    BuryPointer(CI.takeASTConsumer());
   } else {
     if (!isCurrentFileAST()) {
       CI.setSema(0);
@@ -443,7 +443,7 @@
   // FrontendAction.
   CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
 
-  if (isCurrentFileAST()) {
+  if (DisableFree && isCurrentFileAST()) {
     CI.resetAndLeakSema();
     CI.resetAndLeakASTContext();
     CI.resetAndLeakPreprocessor();


More information about the cfe-commits mailing list