<div dir="ltr">Thanks, should be fixed in r179515.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Apr 14, 2013 at 8:05 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri, Apr 12, 2013 at 7:43 PM, Richard Smith<br>
<<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
> Author: rsmith<br>
> Date: Fri Apr 12 21:43:54 2013<br>
> New Revision: 179447<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=179447&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=179447&view=rev</a><br>
> Log:<br>
> Annotate flavor of TLS variable (statically or dynamically initialized) onto the AST.<br>
<br>
</div>This may've caused some regressions?<br>
<a href="http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-gdb/builds/1855" target="_blank">http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-gdb/builds/1855</a><br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> Added:<br>
>     cfe/trunk/test/PCH/thread-local.cpp<br>
> Modified:<br>
>     cfe/trunk/include/clang/AST/Decl.h<br>
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
>     cfe/trunk/lib/AST/ASTDumper.cpp<br>
>     cfe/trunk/lib/AST/DeclPrinter.cpp<br>
>     cfe/trunk/lib/AST/ExprConstant.cpp<br>
>     cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
>     cfe/trunk/lib/CodeGen/CGDeclCXX.cpp<br>
>     cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
>     cfe/trunk/lib/Sema/SemaDecl.cpp<br>
>     cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
>     cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
>     cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
>     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
>     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
>     cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
>     cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp<br>
>     cfe/trunk/test/Misc/ast-dump-decl.c<br>
>     cfe/trunk/test/Misc/ast-dump-decl.cpp<br>
>     cfe/trunk/test/Sema/thread-specifier.c<br>
><br>
> Modified: cfe/trunk/include/clang/AST/Decl.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/Decl.h (original)<br>
> +++ cfe/trunk/include/clang/AST/Decl.h Fri Apr 12 21:43:54 2013<br>
> @@ -641,6 +641,13 @@ public:<br>
>      ListInit  ///< Direct list-initialization (C++11)<br>
>    };<br>
><br>
> +  /// \brief Kinds of thread-local storage.<br>
> +  enum TLSKind {<br>
> +    TLS_None,   ///< Not a TLS variable.<br>
> +    TLS_Static, ///< TLS with a known-constant initializer.<br>
> +    TLS_Dynamic ///< TLS with a dynamic initializer.<br>
> +  };<br>
> +<br>
>  protected:<br>
>    /// \brief Placeholder type used in Init to denote an unparsed C++ default<br>
>    /// argument.<br>
> @@ -664,7 +671,7 @@ private:<br>
>      friend class ASTDeclReader;<br>
><br>
>      unsigned SClass : 3;<br>
> -    unsigned ThreadSpecified : 1;<br>
> +    unsigned TLSKind : 2;<br>
>      unsigned InitStyle : 2;<br>
><br>
>      /// \brief Whether this variable is the exception variable in a C++ catch<br>
> @@ -687,7 +694,7 @@ private:<br>
>      /// \brief Whether this variable is (C++0x) constexpr.<br>
>      unsigned IsConstexpr : 1;<br>
>    };<br>
> -  enum { NumVarDeclBits = 14 };<br>
> +  enum { NumVarDeclBits = 12 };<br>
><br>
>    friend class ASTDeclReader;<br>
>    friend class StmtIteratorBase;<br>
> @@ -771,9 +778,9 @@ public:<br>
>    }<br>
>    void setStorageClass(StorageClass SC);<br>
><br>
> -  void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; }<br>
> -  bool isThreadSpecified() const {<br>
> -    return VarDeclBits.ThreadSpecified;<br>
> +  void setTLSKind(TLSKind TLS) { VarDeclBits.TLSKind = TLS; }<br>
> +  TLSKind getTLSKind() const {<br>
> +    return static_cast<TLSKind>(VarDeclBits.TLSKind);<br>
>    }<br>
><br>
>    /// hasLocalStorage - Returns true if a variable with function scope<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Apr 12 21:43:54 2013<br>
> @@ -3369,6 +3369,9 @@ def err_non_thread_thread : Error<<br>
>    "non-thread-local declaration of %0 follows thread-local declaration">;<br>
>  def err_thread_non_thread : Error<<br>
>    "thread-local declaration of %0 follows non-thread-local declaration">;<br>
> +def err_thread_thread_different_kind : Error<<br>
> +  "thread-local declaration of %0 with %select{static|dynamic}1 initialization "<br>
> +  "follows declaration with %select{dynamic|static}1 initialization">;<br>
>  def err_redefinition_different_type : Error<<br>
>    "redefinition of %0 with a different type%diff{: $ vs $|}1,2">;<br>
>  def err_redefinition_different_kind : Error<<br>
><br>
> Modified: cfe/trunk/lib/AST/ASTDumper.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ASTDumper.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -853,8 +853,11 @@ void ASTDumper::VisitVarDecl(const VarDe<br>
>    StorageClass SC = D->getStorageClass();<br>
>    if (SC != SC_None)<br>
>      OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);<br>
> -  if (D->isThreadSpecified())<br>
> -    OS << " __thread";<br>
> +  switch (D->getTLSKind()) {<br>
> +  case VarDecl::TLS_None: break;<br>
> +  case VarDecl::TLS_Static: OS << " tls"; break;<br>
> +  case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;<br>
> +  }<br>
>    if (D->isModulePrivate())<br>
>      OS << " __module_private__";<br>
>    if (D->isNRVOVariable())<br>
><br>
> Modified: cfe/trunk/lib/AST/DeclPrinter.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/AST/DeclPrinter.cpp (original)<br>
> +++ cfe/trunk/lib/AST/DeclPrinter.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -641,14 +641,25 @@ void DeclPrinter::VisitLabelDecl(LabelDe<br>
><br>
><br>
>  void DeclPrinter::VisitVarDecl(VarDecl *D) {<br>
> -  StorageClass SC = D->getStorageClass();<br>
> -  if (!Policy.SuppressSpecifiers && SC != SC_None)<br>
> -    Out << VarDecl::getStorageClassSpecifierString(SC) << " ";<br>
> +  if (!Policy.SuppressSpecifiers) {<br>
> +    StorageClass SC = D->getStorageClass();<br>
> +    if (SC != SC_None)<br>
> +      Out << VarDecl::getStorageClassSpecifierString(SC) << " ";<br>
><br>
> -  if (!Policy.SuppressSpecifiers && D->isThreadSpecified())<br>
> -    Out << "__thread ";<br>
> -  if (!Policy.SuppressSpecifiers && D->isModulePrivate())<br>
> -    Out << "__module_private__ ";<br>
> +    switch (D->getTLSKind()) {<br>
> +    case VarDecl::TLS_None:<br>
> +      break;<br>
> +    case VarDecl::TLS_Static:<br>
> +      Out << "_Thread_local ";<br>
> +      break;<br>
> +    case VarDecl::TLS_Dynamic:<br>
> +      Out << "thread_local ";<br>
> +      break;<br>
> +    }<br>
> +<br>
> +    if (D->isModulePrivate())<br>
> +      Out << "__module_private__ ";<br>
> +  }<br>
><br>
>    QualType T = D->getType();<br>
>    if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))<br>
><br>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -999,7 +999,7 @@ static bool CheckLValueConstantExpressio<br>
>    // Check if this is a thread-local variable.<br>
>    if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {<br>
>      if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {<br>
> -      if (Var->isThreadSpecified())<br>
> +      if (Var->getTLSKind())<br>
>          return false;<br>
>      }<br>
>    }<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -198,7 +198,7 @@ CodeGenFunction::CreateStaticVarDecl(con<br>
>    if (Linkage != llvm::GlobalValue::InternalLinkage)<br>
>      GV->setVisibility(CurFn->getVisibility());<br>
><br>
> -  if (D.isThreadSpecified())<br>
> +  if (D.getTLSKind())<br>
>      CGM.setTLSMode(GV, D);<br>
><br>
>    return GV;<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -39,7 +39,7 @@ static void EmitDeclInit(CodeGenFunction<br>
>      CodeGenModule &CGM = CGF.CGM;<br>
>      if (lv.isObjCStrong())<br>
>        CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),<br>
> -                                                DeclPtr, D.isThreadSpecified());<br>
> +                                                DeclPtr, D.getTLSKind());<br>
>      else if (lv.isObjCWeak())<br>
>        CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),<br>
>                                                DeclPtr);<br>
> @@ -218,6 +218,9 @@ void CodeGenFunction::EmitCXXGuardedInit<br>
>                "this initialization requires a guard variable, which "<br>
>                "the kernel does not support");<br>
><br>
> +  if (D.getTLSKind())<br>
> +    CGM.ErrorUnsupported(D.getInit(), "dynamic TLS initialization");<br>
> +<br>
>    CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);<br>
>  }<br>
><br>
> @@ -254,6 +257,9 @@ void<br>
>  CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,<br>
>                                              llvm::GlobalVariable *Addr,<br>
>                                              bool PerformInit) {<br>
> +  if (D->getTLSKind())<br>
> +    ErrorUnsupported(D->getInit(), "dynamic TLS initialization");<br>
> +<br>
>    llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);<br>
><br>
>    // Create a variable initialization function.<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -1667,7 +1667,7 @@ static void setObjCGCLValueClass(const A<br>
>      if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {<br>
>        if (VD->hasGlobalStorage()) {<br>
>          LV.setGlobalObjCRef(true);<br>
> -        LV.setThreadLocalRef(VD->isThreadSpecified());<br>
> +        LV.setThreadLocalRef(VD->getTLSKind() != VarDecl::TLS_None);<br>
>        }<br>
>      }<br>
>      LV.setObjCArray(E->getType()->isArrayType());<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -333,7 +333,7 @@ static llvm::GlobalVariable::ThreadLocal<br>
><br>
>  void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,<br>
>                                 const VarDecl &D) const {<br>
> -  assert(D.isThreadSpecified() && "setting TLS mode on non-TLS var!");<br>
> +  assert(D.getTLSKind() && "setting TLS mode on non-TLS var!");<br>
><br>
>    llvm::GlobalVariable::ThreadLocalMode TLM;<br>
>    TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel());<br>
> @@ -1485,7 +1485,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str<br>
>          GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));<br>
>      }<br>
><br>
> -    if (D->isThreadSpecified())<br>
> +    if (D->getTLSKind())<br>
>        setTLSMode(GV, *D);<br>
>    }<br>
><br>
> @@ -1915,7 +1915,7 @@ CodeGenModule::GetLLVMLinkageVarDefiniti<br>
>             ((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||<br>
>               D->getAttr<CommonAttr>()) &&<br>
>             !D->hasExternalStorage() && !D->getInit() &&<br>
> -           !D->getAttr<SectionAttr>() && !D->isThreadSpecified() &&<br>
> +           !D->getAttr<SectionAttr>() && !D->getTLSKind() &&<br>
>             !D->getAttr<WeakImportAttr>()) {<br>
>      // Thread local vars aren't considered common linkage.<br>
>      return llvm::GlobalVariable::CommonLinkage;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -2953,12 +2953,22 @@ void Sema::MergeVarDecl(VarDecl *New, Lo<br>
>      return New->setInvalidDecl();<br>
>    }<br>
><br>
> -  if (New->isThreadSpecified() && !Old->isThreadSpecified()) {<br>
> -    Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();<br>
> -    Diag(Old->getLocation(), diag::note_previous_definition);<br>
> -  } else if (!New->isThreadSpecified() && Old->isThreadSpecified()) {<br>
> -    Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();<br>
> -    Diag(Old->getLocation(), diag::note_previous_definition);<br>
> +  if (New->getTLSKind() != Old->getTLSKind()) {<br>
> +    if (!Old->getTLSKind()) {<br>
> +      Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();<br>
> +      Diag(Old->getLocation(), diag::note_previous_declaration);<br>
> +    } else if (!New->getTLSKind()) {<br>
> +      Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();<br>
> +      Diag(Old->getLocation(), diag::note_previous_declaration);<br>
> +    } else {<br>
> +      // Do not allow redeclaration to change the variable between requiring<br>
> +      // static and dynamic initialization.<br>
> +      // FIXME: GCC allows this, but uses the TLS keyword on the first<br>
> +      // declaration to determine the kind. Do we need to be compatible here?<br>
> +      Diag(New->getLocation(), diag::err_thread_thread_different_kind)<br>
> +        << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);<br>
> +      Diag(Old->getLocation(), diag::note_previous_declaration);<br>
> +    }<br>
>    }<br>
><br>
>    // C++ doesn't have tentative definitions, so go right ahead and check here.<br>
> @@ -4577,7 +4587,7 @@ bool Sema::inferObjCARCLifetime(ValueDec<br>
>    if (VarDecl *var = dyn_cast<VarDecl>(decl)) {<br>
>      // Thread-local variables cannot have lifetime.<br>
>      if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone &&<br>
> -        var->isThreadSpecified()) {<br>
> +        var->getTLSKind()) {<br>
>        Diag(var->getLocation(), diag::err_arc_thread_ownership)<br>
>          << var->getType();<br>
>        return true;<br>
> @@ -4851,9 +4861,9 @@ Sema::ActOnVariableDeclarator(Scope *S,<br>
>        Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),<br>
>             diag::err_thread_unsupported);<br>
>      else<br>
> -      // FIXME: Track which thread specifier was used; they have different<br>
> -      // semantics.<br>
> -      NewVD->setThreadSpecified(true);<br>
> +      NewVD->setTLSKind(TSCS == DeclSpec::TSCS_thread_local<br>
> +                          ? VarDecl::TLS_Dynamic<br>
> +                          : VarDecl::TLS_Static);<br>
>    }<br>
><br>
>    // C99 6.7.4p3<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -284,7 +284,7 @@ static bool mayBeSharedVariable(const De<br>
>    if (isa<FieldDecl>(D))<br>
>      return true;<br>
>    if (const VarDecl *vd = dyn_cast<VarDecl>(D))<br>
> -    return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));<br>
> +    return vd->hasGlobalStorage() && !vd->getTLSKind();<br>
><br>
>    return false;<br>
>  }<br>
> @@ -1656,7 +1656,7 @@ static void handleTLSModelAttr(Sema &S,<br>
>      return;<br>
>    }<br>
><br>
> -  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {<br>
> +  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) {<br>
>      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)<br>
>        << Attr.getName() << ExpectedTLSVar;<br>
>      return;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -165,8 +165,8 @@ OMPThreadPrivateDecl *Sema::CheckOMPThre<br>
>        continue;<br>
>      }<br>
><br>
> -    // Check if threadspecified is set.<br>
> -    if (VD->isThreadSpecified()) {<br>
> +    // Check if this is a TLS variable.<br>
> +    if (VD->getTLSKind()) {<br>
>        Diag(ILoc, diag::err_omp_var_thread_local) << VD;<br>
>        Diag(VD->getLocation(), diag::note_forward_declaration) << VD;<br>
>        continue;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -3842,8 +3842,7 @@ CheckTemplateArgumentAddressOfObjectOrFu<br>
>      }<br>
><br>
>      // A template argument must have static storage duration.<br>
> -    // FIXME: Ensure this works for thread_local as well as __thread.<br>
> -    if (Var->isThreadSpecified()) {<br>
> +    if (Var->getTLSKind()) {<br>
>        S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local)<br>
>          << Arg->getSourceRange();<br>
>        S.Diag(Var->getLocation(), diag::note_template_arg_refers_here);<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -339,7 +339,7 @@ Decl *TemplateDeclInstantiator::VisitVar<br>
>                                   D->getLocation(), D->getIdentifier(),<br>
>                                   DI->getType(), DI,<br>
>                                   D->getStorageClass());<br>
> -  Var->setThreadSpecified(D->isThreadSpecified());<br>
> +  Var->setTLSKind(D->getTLSKind());<br>
>    Var->setInitStyle(D->getInitStyle());<br>
>    Var->setCXXForRangeDecl(D->isCXXForRangeDecl());<br>
>    Var->setConstexpr(D->isConstexpr());<br>
><br>
> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -895,7 +895,7 @@ void ASTDeclReader::VisitVarDecl(VarDecl<br>
>    VisitDeclaratorDecl(VD);<br>
><br>
>    VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];<br>
> -  VD->VarDeclBits.ThreadSpecified = Record[Idx++];<br>
> +  VD->VarDeclBits.TLSKind = Record[Idx++];<br>
>    VD->VarDeclBits.InitStyle = Record[Idx++];<br>
>    VD->VarDeclBits.ExceptionVar = Record[Idx++];<br>
>    VD->VarDeclBits.NRVOVariable = Record[Idx++];<br>
><br>
> Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -677,7 +677,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl<br>
>    VisitRedeclarable(D);<br>
>    VisitDeclaratorDecl(D);<br>
>    Record.push_back(D->getStorageClass());<br>
> -  Record.push_back(D->isThreadSpecified());<br>
> +  Record.push_back(D->getTLSKind());<br>
>    Record.push_back(D->getInitStyle());<br>
>    Record.push_back(D->isExceptionVariable());<br>
>    Record.push_back(D->isNRVOVariable());<br>
> @@ -766,7 +766,7 @@ void ASTDeclWriter::VisitParmVarDecl(Par<br>
><br>
>    // Check things we know are true of *every* PARM_VAR_DECL, which is more than<br>
>    // just us assuming it.<br>
> -  assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");<br>
> +  assert(!D->getTLSKind() && "PARM_VAR_DECL can't use TLS");<br>
>    assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");<br>
>    assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");<br>
>    assert(D->getPreviousDecl() == 0 && "PARM_VAR_DECL can't be redecl");<br>
> @@ -1515,7 +1515,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs()<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo<br>
>    // VarDecl<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass<br>
> -  Abv->Add(BitCodeAbbrevOp(0));                       // isThreadSpecified<br>
> +  Abv->Add(BitCodeAbbrevOp(0));                       // getTLSKind<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // isExceptionVariable<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // isNRVOVariable<br>
> @@ -1594,7 +1594,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs()<br>
>    Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo<br>
>    // VarDecl<br>
>    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass<br>
> -  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isThreadSpecified<br>
> +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getTLSKind<br>
>    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer<br>
>    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable<br>
>    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable<br>
><br>
> Modified: cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp (original)<br>
> +++ cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -4,16 +4,20 @@ namespace std {<br>
>    typedef decltype(nullptr) nullptr_t;<br>
>  }<br>
><br>
> -template<int *ip> struct IP {  // expected-note 4 {{template parameter is declared here}}<br>
> +template<int *ip> struct IP {  // expected-note 5 {{template parameter is declared here}}<br>
>    IP<ip> *ip2;<br>
>  };<br>
><br>
> +template<int &ip> struct IR {};<br>
> +<br>
>  constexpr std::nullptr_t get_nullptr() { return nullptr; }<br>
><br>
>  constexpr std::nullptr_t np = nullptr;<br>
><br>
>  std::nullptr_t nonconst_np; // expected-note{{declared here}}<br>
><br>
> +thread_local int tl; // expected-note {{refers here}}<br>
> +<br>
>  IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}<br>
>  IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}<br>
>  IP<nullptr> ip2;<br>
> @@ -23,6 +27,9 @@ IP<np> ip5;<br>
>  IP<nonconst_np> ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \<br>
>  // expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}}<br>
>  IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}}<br>
> +IP<&tl> ip7; // expected-error{{non-type template argument of type 'int *' is not a constant expression}}<br>
> +<br>
> +IR<tl> ir1; // expected-error{{non-type template argument refers to thread-local object}}<br>
><br>
>  struct X { };<br>
>  template<int X::*pm> struct PM { // expected-note 2 {{template parameter is declared here}}<br>
><br>
> Modified: cfe/trunk/test/Misc/ast-dump-decl.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.c?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.c?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Misc/ast-dump-decl.c (original)<br>
> +++ cfe/trunk/test/Misc/ast-dump-decl.c Fri Apr 12 21:43:54 2013<br>
> @@ -139,7 +139,7 @@ extern int TestVarDeclSC;<br>
>  // CHECK:      VarDecl{{.*}} TestVarDeclSC 'int' extern<br>
><br>
>  __thread int TestVarDeclThread;<br>
> -// CHECK:      VarDecl{{.*}} TestVarDeclThread 'int' __thread<br>
> +// CHECK:      VarDecl{{.*}} TestVarDeclThread 'int' tls{{$}}<br>
><br>
>  __module_private__ int TestVarDeclPrivate;<br>
>  // CHECK:      VarDecl{{.*}} TestVarDeclPrivate 'int' __module_private__<br>
><br>
> Modified: cfe/trunk/test/Misc/ast-dump-decl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.cpp?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-decl.cpp?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Misc/ast-dump-decl.cpp (original)<br>
> +++ cfe/trunk/test/Misc/ast-dump-decl.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -92,6 +92,9 @@ class TestCXXRecordDeclPack : public T..<br>
>  // CHECK-NEXT:   public 'T'...<br>
>  // CHECK-NEXT:   CXXRecordDecl{{.*}} class TestCXXRecordDeclPack<br>
><br>
> +thread_local int TestThreadLocalInt;<br>
> +// CHECK: TestThreadLocalInt {{.*}} tls_dynamic<br>
> +<br>
>  __module_private__ class TestCXXRecordDeclPrivate;<br>
>  // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPrivate __module_private__<br>
><br>
><br>
> Added: cfe/trunk/test/PCH/thread-local.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/thread-local.cpp?rev=179447&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/thread-local.cpp?rev=179447&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/PCH/thread-local.cpp (added)<br>
> +++ cfe/trunk/test/PCH/thread-local.cpp Fri Apr 12 21:43:54 2013<br>
> @@ -0,0 +1,20 @@<br>
> +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t<br>
> +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s<br>
> +<br>
> +#ifndef HEADER_INCLUDED<br>
> +<br>
> +#define HEADER_INCLUDED<br>
> +extern thread_local int a;<br>
> +extern _Thread_local int b;<br>
> +extern int c;<br>
> +<br>
> +#else<br>
> +<br>
> +_Thread_local int a; // expected-error {{thread-local declaration of 'a' with static initialization follows declaration with dynamic initialization}}<br>
> +// expected-note@7 {{previous declaration is here}}<br>
> +thread_local int b; // expected-error {{thread-local declaration of 'b' with dynamic initialization follows declaration with static initialization}}<br>
> +// expected-note@8 {{previous declaration is here}}<br>
> +thread_local int c; // expected-error {{thread-local declaration of 'c' follows non-thread-local declaration}}<br>
> +// expected-note@9 {{previous declaration is here}}<br>
> +<br>
> +#endif<br>
><br>
> Modified: cfe/trunk/test/Sema/thread-specifier.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/thread-specifier.c?rev=179447&r1=179446&r2=179447&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/thread-specifier.c?rev=179447&r1=179446&r2=179447&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Sema/thread-specifier.c (original)<br>
> +++ cfe/trunk/test/Sema/thread-specifier.c Fri Apr 12 21:43:54 2013<br>
> @@ -59,11 +59,18 @@ int f(__thread int t7) { // expected-err<br>
>  }<br>
><br>
>  __thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}}<br>
> -__thread int t15; // expected-note {{previous definition is here}}<br>
> +__thread int t15; // expected-note {{previous declaration is here}}<br>
>  extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}<br>
> -extern int t16; // expected-note {{previous definition is here}}<br>
> +extern int t16; // expected-note {{previous declaration is here}}<br>
>  __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}}<br>
><br>
> +#ifdef CXX11<br>
> +extern thread_local int t17; // expected-note {{previous declaration is here}}<br>
> +_Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}}<br>
> +extern _Thread_local int t18; // expected-note {{previous declaration is here}}<br>
> +thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}}<br>
> +#endif<br>
> +<br>
>  // PR13720<br>
>  __thread int thread_int;<br>
>  int *thread_int_ptr = &thread_int;<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>