<div dir="ltr">On Mon, Sep 23, 2013 at 9:01 PM, Alexey Bataev <span dir="ltr"><<a href="mailto:a.bataev@hotmail.com" target="_blank">a.bataev@hotmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi doug.gregor, eli.friedman, gribozavr, cbergstrom, hfinkel, wwwwpan,<br>
<br>
Improved variable lookup procedure for threadprivate variables.<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D1746" target="_blank">http://llvm-reviews.chandlerc.com/D1746</a><br>
<br>
Files:<br>
  test/OpenMP/threadprivate_ast_print.cpp<br>
  test/OpenMP/threadprivate_messages.cpp<br>
  lib/Sema/SemaOpenMP.cpp<br>
  lib/AST/DeclPrinter.cpp<br>
<br>
Index: test/OpenMP/threadprivate_ast_print.cpp<br>
===================================================================<br>
--- test/OpenMP/threadprivate_ast_print.cpp<br>
+++ test/OpenMP/threadprivate_ast_print.cpp<br>
@@ -15,7 +15,7 @@<br>
  static int b;<br>
 // CHECK: static int b;<br>
 #pragma omp threadprivate(b)<br>
-// CHECK-NEXT: #pragma omp threadprivate(b)<br>
+// CHECK-NEXT: #pragma omp threadprivate(St1::b)<br>
 } d;<br>
<br>
 int a, b;<br>
@@ -38,6 +38,15 @@<br>
 //CHECK-NEXT: static T v;<br>
 //CHECK-NEXT: #pragma omp threadprivate(v)<br>
<br>
+namespace ns{<br>
+  int a;<br>
+}<br>
+// CHECK: namespace ns {<br>
+// CHECK-NEXT: int a;<br>
+// CHECK-NEXT: }<br>
+#pragma omp threadprivate(ns::a)<br>
+// CHECK-NEXT: #pragma omp threadprivate(ns::a)<br>
+<br>
 int main () {<br>
   static int a;<br>
 // CHECK: static int a;<br>
Index: test/OpenMP/threadprivate_messages.cpp<br>
===================================================================<br>
--- test/OpenMP/threadprivate_messages.cpp<br>
+++ test/OpenMP/threadprivate_messages.cpp<br>
@@ -60,12 +60,12 @@<br>
 #pragma omp threadprivate (g)<br>
<br>
 namespace ns {<br>
-  int m; // expected-note 2 {{'m' defined here}}<br>
+  int m;<br>
 #pragma omp threadprivate (m)<br>
 }<br>
 #pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}}<br>
-#pragma omp threadprivate (ns::m) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'ns::m' variable declaration}}<br>
-#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}}<br>

+#pragma omp threadprivate (ns::m) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'ns::m'}}<br>
+#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'}}<br>

<br>
 const int h = 12;<br>
 const volatile int i = 10;<br>
Index: lib/Sema/SemaOpenMP.cpp<br>
===================================================================<br>
--- lib/Sema/SemaOpenMP.cpp<br>
+++ lib/Sema/SemaOpenMP.cpp<br>
@@ -428,7 +428,9 @@<br>
   //   A threadprivate directive for static block-scope variables must appear<br>
   //   in the scope of the variable and not in a nested scope.<br>
   NamedDecl *ND = cast<NamedDecl>(VD);<br>
-  if (!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {<br>
+  if ((!getCurLexicalContext()->isFileContext() ||<br>
+       !VD->getDeclContext()->isFileContext()) &&<br>
+       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {<br>
     Diag(Id.getLoc(), diag::err_omp_var_scope)<br>
       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;<br>
     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==<br></blockquote><div><br></div><div>The comments before this check list four distinct rules for different kinds of variables.  Please implement them explicitly.</div>
<div> </div><div>-Eli</div></div><br></div></div>