Hi doug.gregor, gribozavr, cbergstrom, hfinkel, wwwwpan,

1. Fixed constructor of shared clause.
2. Some macros for clauses processing are replaced by private template methods.
3. Additional checks in sema analysis of OpenMP clauses.
4. Fixed rules in sema for scope analysis in OpenMP threadprivate directive.

http://llvm-reviews.chandlerc.com/D1725

Files:
  test/OpenMP/threadprivate_ast_print.cpp
  test/OpenMP/threadprivate_messages.cpp
  include/clang/AST/StmtOpenMP.h
  include/clang/AST/RecursiveASTVisitor.h
  tools/libclang/RecursiveASTVisitor.h
  tools/libclang/CIndex.cpp
  lib/Sema/TreeTransform.h
  lib/Sema/SemaOpenMP.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Serialization/ASTWriterStmt.cpp
Index: test/OpenMP/threadprivate_ast_print.cpp
===================================================================
--- test/OpenMP/threadprivate_ast_print.cpp
+++ test/OpenMP/threadprivate_ast_print.cpp
@@ -15,7 +15,7 @@
  static int b;
 // CHECK: static int b;
 #pragma omp threadprivate(b)
-// CHECK-NEXT: #pragma omp threadprivate(b)
+// CHECK-NEXT: #pragma omp threadprivate(St1::b)
 } d;
 
 int a, b;
@@ -38,6 +38,15 @@
 //CHECK-NEXT: static T v;
 //CHECK-NEXT: #pragma omp threadprivate(v)
 
+namespace ns{
+ int a;
+}
+// CHECK: namespace ns {
+// CHECK-NEXT: int a;
+// CHECK-NEXT: }
+#pragma omp threadprivate(ns::a)
+// CHECK-NEXT: #pragma omp threadprivate(ns::a)
+
 int main () {
   static int a;
 // CHECK: static int a;
Index: test/OpenMP/threadprivate_messages.cpp
===================================================================
--- test/OpenMP/threadprivate_messages.cpp
+++ test/OpenMP/threadprivate_messages.cpp
@@ -60,12 +60,12 @@
 #pragma omp threadprivate (g)
 
 namespace ns {
-  int m; // expected-note 2 {{'m' defined here}}
+  int m;
 #pragma omp threadprivate (m)
 }
 #pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}}
-#pragma omp threadprivate (ns::m) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'ns::m' variable declaration}}
-#pragma omp threadprivate (ns:m) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'ns::m' variable declaration}}
+#pragma omp threadprivate (ns::m) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'ns::m'}}
+#pragma omp threadprivate (ns:m) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'ns::m'}}
 
 const int h = 12;
 const volatile int i = 10;
Index: include/clang/AST/StmtOpenMP.h
===================================================================
--- include/clang/AST/StmtOpenMP.h
+++ include/clang/AST/StmtOpenMP.h
@@ -275,7 +275,7 @@
   /// \param N Number of variables.
   ///
   explicit OMPSharedClause(unsigned N)
-    : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
+    : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()),
       OMPVarList<OMPSharedClause>(SourceLocation(), N) { }
 public:
   /// \brief Creates clause with a list of variables \a VL.
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -426,6 +426,9 @@
 #define OPENMP_CLAUSE(Name, Class)                                      \
   bool Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
+  /// \brief Process clauses with list of variables.
+  template <typename T>
+  void VisitOMPClauseList(T *Node);
 
   struct EnqueueJob {
     Stmt *S;
@@ -2348,26 +2351,27 @@
   return true;
 }
 
-#define PROCESS_OMP_CLAUSE_LIST(Class, Node)                                   \
-  for (OMPVarList<Class>::varlist_iterator I = Node->varlist_begin(),          \
-                                           E = Node->varlist_end();            \
-         I != E; ++I)                                                          \
+template<typename Derived>
+template<typename T>
+void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (typename T::varlist_iterator I = Node->varlist_begin(),
+                                    E = Node->varlist_end();
+         I != E; ++I)
     TraverseStmt(*I);
+}
 
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
+  VisitOMPClauseList(C);
   return true;
 }
 
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
+  VisitOMPClauseList(C);
   return true;
 }
 
-#undef PROCESS_OMP_CLAUSE_LIST
-
 // FIXME: look at the following tricky-seeming exprs to see if we
 // need to recurse on anything.  These are ones that have methods
 // returning decls or qualtypes or nestednamespecifier -- though I'm
Index: tools/libclang/RecursiveASTVisitor.h
===================================================================
--- tools/libclang/RecursiveASTVisitor.h
+++ tools/libclang/RecursiveASTVisitor.h
@@ -410,6 +410,9 @@
 #define OPENMP_CLAUSE(Name, Class)                                      \
   bool Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
+  /// \brief Process clauses with list of variables.
+  template <typename T>
+  void VisitOMPClauseList(T *Node);
 
   typedef SmallVector<Stmt *, 16> StmtsTy;
   typedef SmallVector<StmtsTy *, 4> QueuesTy;
@@ -2326,26 +2329,27 @@
   return true;
 }
 
-#define PROCESS_OMP_CLAUSE_LIST(Class, Node)                                   \
-  for (OMPVarList<Class>::varlist_iterator I = Node->varlist_begin(),          \
-                                           E = Node->varlist_end();            \
-         I != E; ++I)                                                          \
+template<typename Derived>
+template<typename T>
+void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (typename T::varlist_iterator I = Node->varlist_begin(),
+                                    E = Node->varlist_end();
+         I != E; ++I)
     TraverseStmt(*I);
+}
 
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
+  VisitOMPClauseList(C);
   return true;
 }
 
 template<typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
+  VisitOMPClauseList(C);
   return true;
 }
 
-#undef PROCESS_OMP_CLAUSE_LIST
-
 // FIXME: look at the following tricky-seeming exprs to see if we
 // need to recurse on anything.  These are ones that have methods
 // returning decls or qualtypes or nestednamespecifier -- though I'm
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1920,28 +1920,34 @@
 namespace {
 class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
   EnqueueVisitor *Visitor;
+  /// \brief Process clauses with list of variables.
+  template <typename T>
+  void VisitOMPClauseList(T *Node);
 public:
   OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
 #define OPENMP_CLAUSE(Name, Class)                                             \
   void Visit##Class(const Class *C);
 #include "clang/Basic/OpenMPKinds.def"
 };
 
 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
-#define PROCESS_OMP_CLAUSE_LIST(Class, Node)                                   \
-  for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(),    \
-                                                 E = Node->varlist_end();      \
-         I != E; ++I)                                                          \
+
+template<typename T>
+void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
+  for (typename T::varlist_const_iterator I = Node->varlist_begin(),
+                                          E = Node->varlist_end();
+         I != E; ++I)
     Visitor->AddStmt(*I);
+}
 
 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
+  VisitOMPClauseList(C);
 }
 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
+  VisitOMPClauseList(C);
 }
-#undef PROCESS_OMP_CLAUSE_LIST
 }
+
 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
   unsigned size = WL.size();
   OMPClauseEnqueue Visitor(this);
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -6325,8 +6325,8 @@
 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());
-  for (OMPVarList<OMPPrivateClause>::varlist_iterator I = C->varlist_begin(),
-                                                      E = C->varlist_end();
+  for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(),
+                                          E = C->varlist_end();
        I != E; ++I) {
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
     if (EVar.isInvalid())
@@ -6344,8 +6344,8 @@
 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();
+  for (OMPSharedClause::varlist_iterator I = C->varlist_begin(),
+                                         E = C->varlist_end();
        I != E; ++I) {
     ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
     if (EVar.isInvalid())
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -428,7 +428,9 @@
   //   A threadprivate directive for static block-scope variables must appear
   //   in the scope of the variable and not in a nested scope.
   NamedDecl *ND = cast<NamedDecl>(VD);
-  if (!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
+  if ((!getCurLexicalContext()->isFileContext() ||
+       !VD->getDeclContext()->isFileContext()) &&
+       !isDeclInScope(ND, getCurLexicalContext(), getCurScope())) {
     Diag(Id.getLoc(), diag::err_omp_var_scope)
       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
@@ -717,7 +719,8 @@
   SmallVector<Expr *, 8> Vars;
   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
        I != E; ++I) {
-    if (*I && isa<DependentScopeDeclRefExpr>(*I)) {
+    assert(*I && "NULL expr in OpenMP private clause.");
+    if (isa<DependentScopeDeclRefExpr>(*I)) {
       // It will be analyzed later.
       Vars.push_back(*I);
       continue;
@@ -849,7 +852,8 @@
   SmallVector<Expr *, 8> Vars;
   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
        I != E; ++I) {
-    if (*I && isa<DependentScopeDeclRefExpr>(*I)) {
+    assert(*I && "NULL expr in OpenMP shared clause.");
+    if (isa<DependentScopeDeclRefExpr>(*I)) {
       // It will be analyzed later.
       Vars.push_back(*I);
       continue;
Index: lib/AST/DeclPrinter.cpp
===================================================================
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -1189,8 +1189,9 @@
     for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
                                                 E = D->varlist_end();
                                                 I != E; ++I) {
-      Out << (I == D->varlist_begin() ? '(' : ',')
-          << *cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+      Out << (I == D->varlist_begin() ? '(' : ',');
+      NamedDecl *ND = cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+      ND->printQualifiedName(Out);
     }
     Out << ")";
   }
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -586,6 +586,9 @@
 namespace {
 class OMPClausePrinter : public OMPClauseVisitor<OMPClausePrinter> {
   raw_ostream &OS;
+  /// \brief Process clauses with list of variables.
+  template <typename T>
+  void VisitOMPClauseList(T *Node, char StartSym);
 public:
   OMPClausePrinter(raw_ostream &OS) : OS(OS) { }
 #define OPENMP_CLAUSE(Name, Class)                              \
@@ -599,30 +602,31 @@
      << ")";
 }
 
-#define PROCESS_OMP_CLAUSE_LIST(Class, Node, StartSym)                         \
-  for (OMPVarList<Class>::varlist_iterator I = Node->varlist_begin(),          \
-                                           E = Node->varlist_end();            \
-         I != E; ++I)                                                          \
-    OS << (I == Node->varlist_begin() ? StartSym : ',')                        \
+template<typename T>
+void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
+  for (typename T::varlist_iterator I = Node->varlist_begin(),
+                                    E = Node->varlist_end();
+         I != E; ++I)
+    OS << (I == Node->varlist_begin() ? StartSym : ',')
        << *cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+}
 
 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "private";
-    PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, Node, '(')
+    VisitOMPClauseList(Node, '(');
     OS << ")";
   }
 }
 
 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "shared";
-    PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, Node, '(')
+    VisitOMPClauseList(Node, '(');
     OS << ")";
   }
 }
 
-#undef PROCESS_OMP_CLAUSE_LIST
 }
 
 //===----------------------------------------------------------------------===//
Index: lib/AST/StmtProfile.cpp
===================================================================
--- lib/AST/StmtProfile.cpp
+++ lib/AST/StmtProfile.cpp
@@ -255,27 +255,32 @@
 namespace {
 class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
   StmtProfiler *Profiler;
+  /// \brief Process clauses with list of variables.
+  template <typename T>
+  void VisitOMPClauseList(T *Node);
 public:
   OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
 #define OPENMP_CLAUSE(Name, Class)                                             \
   void Visit##Class(const Class *C);
 #include "clang/Basic/OpenMPKinds.def"
 };
 
 void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
-#define PROCESS_OMP_CLAUSE_LIST(Class, Node)                                   \
-  for (OMPVarList<Class>::varlist_const_iterator I = Node->varlist_begin(),    \
-                                                 E = Node->varlist_end();      \
-         I != E; ++I)                                                          \
+
+template<typename T>
+void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
+  for (typename T::varlist_const_iterator I = Node->varlist_begin(),
+                                          E = Node->varlist_end();
+         I != E; ++I)
     Profiler->VisitStmt(*I);
+}
 
 void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPPrivateClause, C)
+  VisitOMPClauseList(C);
 }
 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
-  PROCESS_OMP_CLAUSE_LIST(OMPSharedClause, C)
+  VisitOMPClauseList(C);
 }
-#undef PROCESS_OMP_CLAUSE_LIST
 }
 
 void
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -1706,17 +1706,17 @@
 void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
-  for (OMPVarList<OMPPrivateClause>::varlist_iterator I = C->varlist_begin(),
-                                                      E = C->varlist_end();
+  for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(),
+                                          E = C->varlist_end();
        I != E; ++I)
     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();
+  for (OMPSharedClause::varlist_iterator I = C->varlist_begin(),
+                                         E = C->varlist_end();
        I != E; ++I)
     Writer->Writer.AddStmt(*I);
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to